Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature CLS2 -1085 Accept any valid string for Eyblead #5852

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 4.2.16 on 2024-12-11 21:51

import django.contrib.postgres.fields
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('investment_lead', '0010_alter_eyblead_hiring'),
]

operations = [
migrations.AlterField(
model_name='eyblead',
name='intent',
field=django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=256), default=list, size=6),
),
migrations.AlterField(
model_name='eyblead',
name='landing_timeframe',
field=models.CharField(blank=True, default='', max_length=256),
),
migrations.AlterField(
model_name='eyblead',
name='spend',
field=models.CharField(blank=True, default='', max_length=256),
),
]
49 changes: 2 additions & 47 deletions datahub/investment_lead/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,50 +39,6 @@ class EYBLead(InvestmentLead):
user's unique ID.
"""

class IntentChoices(models.TextChoices):
SET_UP_NEW_PREMISES = 'SET_UP_NEW_PREMISES', 'Set up new premises'
SET_UP_A_NEW_DISTRIBUTION_CENTRE = (
'SET_UP_A_NEW_DISTRIBUTION_CENTRE',
'Set up a new distribution centre',
)
ONWARD_SALES_AND_EXPORTS_FROM_THE_UK = (
'ONWARD_SALES_AND_EXPORTS_FROM_THE_UK',
'Onward sales and exports from the UK',
)
RESEARCH_DEVELOP_AND_COLLABORATE = (
'RESEARCH_DEVELOP_AND_COLLABORATE',
'Research, develop and collaborate',
)
FIND_PEOPLE_WITH_SPECIALIST_SKILLS = (
'FIND_PEOPLE_WITH_SPECIALIST_SKILLS',
'Find people with specialist skills',
)
OTHER = 'OTHER', 'Other'

class SpendChoices(models.TextChoices):
# Legacy choice
FIVE_HUNDRED_THOUSAND_ONE_TO_ONE_MILLION = '500001-1000000', '£500,001 - £1,000,000'
ONE_MILLION_ONE_TO_TWO_MILLION = '1000001-2000000', '£1,000,001 - £2,000,000'
TWO_MILLION_ONE_TO_FIVE_MILLION = '2000001-5000000', '£2,000,001 - £5,000,000'
FIVE_MILLION_ONE_TO_TEN_MILLION = '5000001-10000000', '£5,000,001 - £10,000,000'
TEN_MILLION_ONE_PLUS = '10000001+', 'More than £10 million'
SPECIFIC_AMOUNT = 'SPECIFIC_AMOUNT', 'Specific amount'

# Current choices
LESS_THAN_TEN_THOUSAND = '0-9999', 'Less than £10,000'
TEN_THOUSAND_TO_FIVE_HUNDRED_THOUSAND = '10000-500000', '£10,000 to £500,000'
FIVE_HUNDRED_THOUSAND_TO_ONE_MILLION = '500000-1000000', '£500,000 to £1 million'
ONE_MILLION_TO_TWO_MILLION = '1000000-2000000', '£1 million to £2 million'
TWO_MILLION_TO_FIVE_MILLION = '2000000-5000000', '£2 million to £5 million'
FIVE_MILLION_TO_TEN_MILLION = '5000000-10000000', '£5 million to £10 million'
MORE_THAN_TEN_MILLION = '10000000+', 'More than £10 million'

class LandingTimeframeChoices(models.TextChoices):
UNDER_SIX_MONTHS = 'UNDER_SIX_MONTHS', 'In the next 6 months'
SIX_TO_TWELVE_MONTHS = 'SIX_TO_TWELVE_MONTHS', '6 to 12 months'
ONE_TO_TWO_YEARS = 'ONE_TO_TWO_YEARS', '1 to 2 years'
OVER_TWO_YEARS = 'OVER_TWO_YEARS', "In more than 2 years' time"

# EYB triage fields
triage_hashed_uuid = models.CharField(max_length=CHAR_FIELD_MAX_LENGTH, default='', blank=True)
triage_created = models.DateTimeField(null=True, blank=True)
Expand All @@ -101,7 +57,7 @@ class LandingTimeframeChoices(models.TextChoices):
default=list,
)
intent = ArrayField(
models.CharField(max_length=CHAR_FIELD_MAX_LENGTH, choices=IntentChoices.choices),
models.CharField(max_length=CHAR_FIELD_MAX_LENGTH),
size=6,
default=list,
)
Expand All @@ -124,7 +80,7 @@ class LandingTimeframeChoices(models.TextChoices):
max_length=CHAR_FIELD_MAX_LENGTH, default='', blank=True,
)
spend = models.CharField(
max_length=CHAR_FIELD_MAX_LENGTH, choices=SpendChoices.choices, default='', blank=True,
max_length=CHAR_FIELD_MAX_LENGTH, default='', blank=True,
)
spend_other = models.CharField(max_length=CHAR_FIELD_MAX_LENGTH, default='', blank=True)
is_high_value = models.BooleanField(default=None, null=True)
Expand Down Expand Up @@ -170,7 +126,6 @@ class LandingTimeframeChoices(models.TextChoices):
default='',
max_length=CHAR_FIELD_MAX_LENGTH,
blank=True,
choices=LandingTimeframeChoices.choices,
)

# Related fields
Expand Down
25 changes: 2 additions & 23 deletions datahub/investment_lead/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ class Meta(BaseEYBLeadSerializer.Meta):
sectorSubSub = serializers.CharField( # noqa: N815
read_only=True, required=False, allow_null=True,
)
# Can't use MultipleChoiceField here as it returns a set rather than a list and raises db error
intent = serializers.ListField(required=False, allow_null=True, allow_empty=True, default=list)
intentOther = serializers.CharField( # noqa: N815
source='intent_other', required=False, allow_null=True, allow_blank=True, default='',
Expand All @@ -198,8 +197,7 @@ class Meta(BaseEYBLeadSerializer.Meta):
hiring = serializers.CharField(
required=False, allow_null=True, allow_blank=True, default='',
)
spend = serializers.ChoiceField(
choices=EYBLead.SpendChoices.choices,
spend = serializers.CharField(
required=False, allow_null=True, allow_blank=True, default='',
)
spendOther = serializers.CharField( # noqa: N815
Expand Down Expand Up @@ -379,9 +377,8 @@ class Meta(BaseEYBLeadSerializer.Meta):
agreeInfoEmail = serializers.BooleanField( # noqa: N815
source='agree_info_email', required=False, allow_null=True, default=None,
)
landingTimeframe = serializers.ChoiceField( # noqa: N815
landingTimeframe = serializers.CharField( # noqa: N815
source='landing_timeframe',
choices=EYBLead.LandingTimeframeChoices.choices,
required=False,
allow_null=True,
allow_blank=True,
Expand Down Expand Up @@ -499,21 +496,3 @@ class Meta(BaseEYBLeadSerializer.Meta):
)
company = NestedRelatedField(Company)
investment_projects = NestedRelatedField(InvestmentProject, many=True)

def get_related_fields_representation(self, instance):
"""Provides related fields in a representation-friendly format.

Specifically, we want to convert `UPPER_CASE` values to `Sentence case` labels
for choice fields.
"""
return {
'intent': [
EYBLead.IntentChoices(intent_choice).label
for intent_choice in instance.intent
],
'spend': EYBLead.SpendChoices(instance.spend).label
if instance.spend else None,
'landing_timeframe': EYBLead.LandingTimeframeChoices(
instance.landing_timeframe,
).label if instance.landing_timeframe else None,
}
45 changes: 37 additions & 8 deletions datahub/investment_lead/test/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,40 @@
from datahub.company.test.factories import CompanyFactory
from datahub.core import constants
from datahub.core.test.factories import to_many_field
from datahub.investment_lead.models import EYBLead
from datahub.metadata.models import Sector


HIRING_CHOICES = ['1-10', '11-50', '51-100', '101+', 'NO_PLANS_TO_HIRE_YET']
INTENT_CHOICES = [
'SET_UP_NEW_PREMISES',
'SET_UP_A_NEW_DISTRIBUTION_CENTRE',
'ONWARD_SALES_AND_EXPORTS_FROM_THE_UK',
'RESEARCH_DEVELOP_AND_COLLABORATE',
'FIND_PEOPLE_WITH_SPECIALIST_SKILLS',
'OTHER',
]

SPEND_CHOICES = [
'0-499999',
'500000-1000000',
'1000000-2500000',
'2500000-5000000',
'5000000+',
]

LANDING_TIME_FRAME_CHOICES = [
'UNDER_SIX_MONTHS',
'SIX_TO_TWELVE_MONTHS',
'ONE_TO_TWO_YEARS',
'OVER_TWO_YEARS',
]

HIRING_CHOICES = [
'1-5',
'6-10',
'11-20',
'21+',
'NO_PLANS_TO_HIRE_YET',
]


fake = Faker(locale='en_GB')
Expand All @@ -39,14 +68,14 @@ class Meta:
triage_modified = factory.LazyFunction(datetime.now)
sector = factory.LazyAttribute(lambda o: random.choice(list(Sector.objects.all())))
intent = factory.LazyAttribute(
lambda o: random.sample(EYBLead.IntentChoices.values, k=random.randint(1, 4)),
lambda o: random.sample(INTENT_CHOICES, k=random.randint(1, 4)),
)
intent_other = ''
proposed_investment_region_id = constants.UKRegion.wales.value.id
proposed_investment_city = 'Cardiff'
proposed_investment_location_none = False
hiring = factory.LazyAttribute(lambda o: random.choice(HIRING_CHOICES))
spend = factory.LazyAttribute(lambda o: random.choice(EYBLead.SpendChoices.values))
spend = factory.LazyAttribute(lambda o: random.choice(SPEND_CHOICES))
spend_other = ''
is_high_value = factory.Faker('pybool')

Expand All @@ -70,7 +99,7 @@ class Meta:
agree_terms = factory.Faker('pybool')
agree_info_email = factory.Faker('pybool')
landing_timeframe = factory.LazyAttribute(
lambda o: random.choice(EYBLead.LandingTimeframeChoices.values),
lambda o: random.choice(LANDING_TIME_FRAME_CHOICES),
)

# EYB marketing fields
Expand Down Expand Up @@ -117,7 +146,7 @@ def eyb_lead_user_record_faker(overrides: dict | None = None) -> dict:
'telephoneNumber': fake.phone_number(),
'agreeTerms': fake.pybool(),
'agreeInfoEmail': fake.pybool(),
'landingTimeframe': random.choice(EYBLead.LandingTimeframeChoices.values),
'landingTimeframe': random.choice(LANDING_TIME_FRAME_CHOICES),
}
if overrides:
data.update(overrides)
Expand All @@ -143,13 +172,13 @@ def eyb_lead_triage_record_faker(overrides: dict | None = None) -> dict:
'sector': level_zero_segment,
'sectorSub': level_one_segment,
'sectorSubSub': level_two_segment,
'intent': random.sample(EYBLead.IntentChoices.values, k=random.randint(1, 4)),
'intent': random.sample(INTENT_CHOICES, k=random.randint(1, 4)),
'intentOther': '',
'location': constants.UKRegion.wales.value.name,
'locationCity': 'Cardiff',
'locationNone': False,
'hiring': random.choice(HIRING_CHOICES),
'spend': random.choice(EYBLead.SpendChoices.values),
'spend': random.choice(SPEND_CHOICES),
'spendOther': '',
'isHighValue': fake.pybool(),
}
Expand Down
12 changes: 4 additions & 8 deletions datahub/investment_lead/test/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,14 @@ def test_related_field_conversion(self, eyb_lead_triage_data):
assert validated_data['sector'].pk == mining_sector.pk
assert validated_data['proposed_investment_region'].pk == wales_region.pk

def test_create_lead_from_invalid_choice_and_related_data(self, eyb_lead_triage_data):
"""Tests invalid choice-field and related-field data raises validation errors."""
def test_create_lead_from_invalid_choice(self, eyb_lead_triage_data):
"""Tests invalid choice-field data raises validation errors."""
eyb_lead_triage_data.update({
'location': 'Invalid location name',
'spend': 'Invalid spend choice',
})
serializer = CreateEYBLeadTriageSerializer(data=eyb_lead_triage_data)
assert not serializer.is_valid()
assert 'location' in serializer.errors
assert 'spend' in serializer.errors

def test_create_lead_from_invalid_sector_data(self, eyb_lead_triage_data):
"""Tests invalid sector data raises validation errors."""
Expand Down Expand Up @@ -232,16 +230,14 @@ def test_related_field_conversion(self, eyb_lead_user_data):
validated_data = serializer.validated_data
assert validated_data['address_country'].pk == canada_country.pk

def test_create_lead_from_invalid_choice_and_related_data(self, eyb_lead_user_data):
"""Tests invalid choice-field and related-field data raises validation errors."""
def test_create_lead_from_invalid_related_data(self, eyb_lead_user_data):
"""Tests invalid related-field data raises validation errors."""
eyb_lead_user_data.update({
'companyLocation': 'Invalid country name',
'landingTimeframe': 'Invalid landing timeframe choice',
})
serializer = CreateEYBLeadUserSerializer(data=eyb_lead_user_data)
assert not serializer.is_valid()
assert 'companyLocation' in serializer.errors
assert 'landingTimeframe' in serializer.errors

@pytest.mark.parametrize(
'value',
Expand Down
10 changes: 3 additions & 7 deletions datahub/investment_lead/test/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,13 @@ def assert_retrieved_eyb_lead_data(instance: EYBLead, data: dict):
assert_datetimes(instance.triage_created, data['triage_created'])
assert_datetimes(instance.triage_modified, data['triage_modified'])
assert str(instance.sector.id) == data['sector']['id']
assert [
EYBLead.IntentChoices(intent_choice).label
for intent_choice in instance.intent
] == data['intent']
assert instance.intent == data['intent']
assert instance.intent_other == data['intent_other']
assert str(instance.proposed_investment_region.id) == data['proposed_investment_region']['id']
assert instance.proposed_investment_city == data['proposed_investment_city']
assert instance.proposed_investment_location_none == data['proposed_investment_location_none']
assert instance.hiring == data['hiring']
assert EYBLead.SpendChoices(instance.spend).label == data['spend']
assert instance.spend == data['spend']
assert instance.spend_other == data['spend_other']
assert instance.is_high_value == data['is_high_value']

Expand All @@ -152,8 +149,7 @@ def assert_retrieved_eyb_lead_data(instance: EYBLead, data: dict):
assert instance.telephone_number == data['telephone_number']
assert instance.agree_terms == data['agree_terms']
assert instance.agree_info_email == data['agree_info_email']
assert EYBLead.LandingTimeframeChoices(instance.landing_timeframe).label \
== data['landing_timeframe']
assert instance.landing_timeframe == data['landing_timeframe']
assert [
str(ip.id) for ip in instance.investment_projects.all()
] == [
Expand Down
Loading