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

(PC-31475)[ADAGE] feat: Add an attribut in brevo for Marseille en Grand #13941

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
9 changes: 8 additions & 1 deletion api/src/pcapi/core/educational/api/offer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from pcapi.core.educational.models import CollectiveOffer
from pcapi.core.educational.models import HasImageMixin
from pcapi.core.educational.utils import get_image_from_url
from pcapi.core.external.attributes.api import update_external_pro
from pcapi.core.mails import transactional as transactional_mails
from pcapi.core.object_storage import store_public_object
from pcapi.core.offerers import api as offerers_api
Expand Down Expand Up @@ -268,7 +269,13 @@ def create_collective_offer(
formats=offer_data.formats, # type: ignore[arg-type]
author=user,
)
collective_offer.bookingEmails = offer_data.booking_emails

emails = offer_data.booking_emails
collective_offer.bookingEmails = emails

# we update pro email data in sendinblue
for email in emails:
update_external_pro(email)
jcicurel-pass marked this conversation as resolved.
Show resolved Hide resolved

db.session.add(collective_offer)
db.session.commit()
Expand Down
3 changes: 3 additions & 0 deletions api/src/pcapi/core/educational/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1873,6 +1873,9 @@ class CollectiveOfferTemplateEducationalRedactor(PcObject, Base, Model):
)


PROGRAM_MARSEILLE_EN_GRAND = "marseille_en_grand"


class EducationalInstitutionProgramAssociation(Base, Model):
"""Association model between EducationalInstitution and
EducationalInstitutionProgram (many-to-many)
Expand Down
17 changes: 17 additions & 0 deletions api/src/pcapi/core/educational/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -1346,3 +1346,20 @@ def fetch_venue_for_new_offer(venue_id: int, requested_provider_id: int) -> offe
if not venue:
raise offerers_exceptions.VenueNotFoundException()
return typing.cast(offerers_models.Venue, venue)


def has_collective_offers_for_program_and_venue_ids(program_name: str, venue_ids: typing.Iterable[str]) -> bool:
query = (
educational_models.CollectiveOffer.query.join(
educational_models.EducationalInstitution, educational_models.CollectiveOffer.institution
)
.join(educational_models.EducationalInstitutionProgram, educational_models.EducationalInstitution.programs)
.filter(
prouzet marked this conversation as resolved.
Show resolved Hide resolved
educational_models.CollectiveOffer.venueId.in_(venue_ids),
educational_models.CollectiveOffer.validation == offer_mixin.OfferValidationStatus.APPROVED,
educational_models.EducationalInstitutionProgram.name == program_name,
)
.exists()
)

return db.session.query(query).scalar()
11 changes: 11 additions & 0 deletions api/src/pcapi/core/external/attributes/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from pcapi.core.bookings import repository as bookings_repository
from pcapi.core.categories import categories
from pcapi.core.educational import models as educational_models
from pcapi.core.educational.repository import has_collective_offers_for_program_and_venue_ids
from pcapi.core.external.attributes import models
from pcapi.core.external.batch import update_user_attributes as update_batch_user
from pcapi.core.external.sendinblue import update_contact_attributes as update_sendinblue_user
Expand Down Expand Up @@ -276,6 +277,7 @@ def get_pro_attributes(email: str) -> models.ProAttributes:
offerers_models.Venue.isVirtual,
offerers_models.Venue.isPermanent,
offerers_models.Venue._bannerUrl,
offerers_models.Venue.adageId,
),
contains_eager(offerers_models.Venue.managingOfferer)
.load_only(offerers_models.Offerer.name)
Expand All @@ -287,12 +289,20 @@ def get_pro_attributes(email: str) -> models.ProAttributes:
.all()
)

venue_ids = {venue.id for venue in venues}
is_eac_meg = has_collective_offers_for_program_and_venue_ids(
educational_models.PROGRAM_MARSEILLE_EN_GRAND, venue_ids
)

if venues:

all_venues += venues
for venue in venues:
offerers_names.add(venue.managingOfferer.name)
offerers_tags.update(tag.label for tag in venue.managingOfferer.tags)

has_individual_offers = offerers_repository.venues_have_offers(*venues)

attributes.update(
{
"dms_application_submitted": any(venue.hasPendingBankInformationApplication for venue in venues),
Expand Down Expand Up @@ -329,6 +339,7 @@ def get_pro_attributes(email: str) -> models.ProAttributes:
departement_code={venue.departementCode for venue in all_venues if venue.departementCode},
postal_code={venue.postalCode for venue in all_venues if venue.postalCode},
has_collective_offers=has_collective_offers,
is_eac_meg=is_eac_meg,
**attributes,
)

Expand Down
1 change: 1 addition & 0 deletions api/src/pcapi/core/external/attributes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class ProAttributes:
has_banner_url: bool | None = (
None # Set to False when at least one permanent venue doesn't have a banner URL, True otherwise
)
is_eac_meg: bool | None = None # At least one collective offer with 'Marseille en Grand'


@dataclass
Expand Down
2 changes: 2 additions & 0 deletions api/src/pcapi/core/external/sendinblue.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class SendinblueAttributes(Enum):
VENUE_NAME = "VENUE_NAME"
VENUE_TYPE = "VENUE_TYPE"
IS_EAC = "IS_EAC"
IS_EAC_MEG = "EAC_MEG"

@classmethod
def list(cls) -> list[str]:
Expand Down Expand Up @@ -244,6 +245,7 @@ def format_user_attributes(attributes: attributes_models.UserAttributes | attrib
SendinblueAttributes.VENUE_NAME.value: _get_attr(attributes, "venues_names", format_list),
SendinblueAttributes.VENUE_TYPE.value: _get_attr(attributes, "venues_types", format_list),
SendinblueAttributes.IS_EAC.value: _get_attr(attributes, "is_eac"),
SendinblueAttributes.IS_EAC_MEG.value: _get_attr(attributes, "is_eac_meg"),
}


Expand Down
2 changes: 1 addition & 1 deletion api/tests/core/bookings/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def test_create_booking(self, mocked_async_index_offer_ids, app):
# 1 - SELECT from offer that I don't get
# 1 - SELECT bookings for the venue ???
# 1 - SELECT feature
with assert_num_queries(35):
with assert_num_queries(36):
booking = api.book_offer(beneficiary=beneficiary, stock_id=stock_id, quantity=1)

# One request should have been sent to Batch to trigger the event
Expand Down
35 changes: 35 additions & 0 deletions api/tests/core/educational/test_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from pcapi.core.educational.models import CollectiveOfferDisplayedStatus
from pcapi.core.offerers import factories as offerers_factories
from pcapi.core.offers.repository import _filter_collective_offers_by_statuses
from pcapi.core.testing import assert_num_queries
from pcapi.core.users import factories as users_factories
from pcapi.models import offer_mixin

Expand Down Expand Up @@ -621,3 +622,37 @@ def test_filter_with_statuses_has_none(self, app):
# Then
assert filtered_nostatus_query.count() == 2
assert set(filtered_nostatus_query.all()) == {pending_offer, booked_offer}


class HasCollectiveOffersForProgramAndVenueIdsTest:

def test_has_collective_offers_for_program_and_venueids_test(self, app):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ce test est pertinent mais n'est pas suffisant pour vérifier que la fonction ici testée est appelée quand il faut. Cf. mon commentaire plus haut. Je pensais à un test dans external_pro_test.py, par exemple avec deux lieux dont le bookingEmail correpond à l'email, dont un avec une offre MEG, mais aucun compte pro n'ayant cet email.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tu as raison, mon push d'hier soir avec ce test n'est pas passé...

program = educational_factories.EducationalInstitutionProgramFactory(name="program")
other_program = educational_factories.EducationalInstitutionProgramFactory(name="other_program")

venue = offerers_factories.VenueFactory()
other_venue = offerers_factories.VenueFactory()

institution = educational_factories.EducationalInstitutionFactory(programs=[program])
other_institution = educational_factories.EducationalInstitutionFactory(programs=[other_program])

_collective_offer_with_program = educational_factories.CollectiveOfferFactory(
venue=venue, institution=institution
)
_collective_offer_without_program = educational_factories.CollectiveOfferFactory(venue=venue)
_collective_offer_with_other_program = educational_factories.CollectiveOfferFactory(
venue=other_venue, institution=other_institution
)

venue_id = venue.id

with assert_num_queries(1):
assert educational_repository.has_collective_offers_for_program_and_venue_ids("program", [venue_id]) == True

assert (
educational_repository.has_collective_offers_for_program_and_venue_ids("other_program", [venue.id]) == False
)

assert (
educational_repository.has_collective_offers_for_program_and_venue_ids("program", [other_venue.id]) == False
)
1 change: 1 addition & 0 deletions api/tests/core/external/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,5 @@
has_bookings=True,
is_eac=False,
has_banner_url=True,
is_eac_meg=False,
)
61 changes: 41 additions & 20 deletions api/tests/core/external/external_pro_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
# 1 query on user table with joinedload
# 1 query on venue table with joinedload
# 2 extra SQL queries: select exists on offer and booking tables
EXPECTED_PRO_ATTR_NUM_QUERIES = 5
# 1 extra query to check if the venue has any related collective offer with 'marseille en grand'
# 1 check if the venue is concerned with marseille_en_grand
EXPECTED_PRO_ATTR_NUM_QUERIES = 6


def _build_params(subs, virt, perman, draft, accep, offer, book, attach, colloff, tploff):
def _build_params(subs, virt, perman, draft, accep, offer, book, attach, colloff, tploff, megoff):
return pytest.param(
subs,
virt,
Expand All @@ -38,25 +40,27 @@ def _build_params(subs, virt, perman, draft, accep, offer, book, attach, colloff
attach,
colloff,
tploff,
megoff,
id=(
f"sub:{subs}, vir:{virt}, per:{perman}, dra:{draft}, "
f"acc:{accep}, off:{offer}, boo:{book}, "
f"att:{attach}, colloff:{colloff}, tploff:{tploff}"
f"att:{attach}, colloff:{colloff}, tploff:{tploff}, megoff:{megoff}"
),
)


@pytest.mark.parametrize(
"enable_subscription,create_virtual,create_permanent,create_dms_draft,create_dms_accepted,"
"create_individual_offer,create_booking,attached,create_collective_offer,create_template_offer",
"create_individual_offer,create_booking,attached,create_collective_offer,create_template_offer,create_collective_offer_meg",
[
# subs, virt, perman, draft, accep, offer, book, attach, colloff, tploff
_build_params(False, False, False, False, False, False, False, "none", False, False),
_build_params(True, False, True, True, False, True, False, "one", True, False),
_build_params(False, True, False, False, True, True, False, "all", False, True),
_build_params(True, True, True, True, True, True, True, "none", True, True),
_build_params(False, True, True, False, True, False, False, "one", True, False),
_build_params(True, True, True, True, True, True, True, "all", True, True),
# subs, virt, perman, draft, accep, offer, book, attach, colloff, tploff, megoff
_build_params(False, False, False, False, False, False, False, "none", False, False, False),
_build_params(True, False, True, True, False, True, False, "one", True, False, False),
_build_params(False, True, False, False, True, True, False, "all", False, True, False),
_build_params(True, True, True, True, True, True, True, "none", True, True, False),
_build_params(False, True, True, False, True, False, False, "one", True, False, False),
_build_params(True, True, True, True, True, True, True, "all", True, True, False),
_build_params(False, False, False, False, False, False, False, "none", True, False, True),
],
)
def test_update_external_pro_user_attributes(
Expand All @@ -70,6 +74,7 @@ def test_update_external_pro_user_attributes(
attached,
create_collective_offer,
create_template_offer,
create_collective_offer_meg,
):
email = "[email protected]"

Expand All @@ -89,6 +94,19 @@ def test_update_external_pro_user_attributes(
if attached in ("one", "all"):
offerers_factories.UserOffererFactory(user=ProFactory(), offerer=offerer1)
offerers_factories.UserOffererFactory(user=pro_user, offerer=offerer1)

collective_offers = []
if create_collective_offer:
if create_collective_offer_meg:
program = educational_factories.EducationalInstitutionProgramFactory(name="marseille_en_grand")
institution = educational_factories.EducationalInstitutionFactory(programs=[program])

collective_offer = educational_factories.CollectiveOfferFactory(isActive=True, institution=institution)
else:
collective_offer = educational_factories.CollectiveOfferFactory(isActive=True)

collective_offers.append(collective_offer)

venue1 = offerers_factories.VenueFactory(
managingOfferer=offerer1,
name="Cinéma de la plage",
Expand All @@ -100,9 +118,8 @@ def test_update_external_pro_user_attributes(
isPermanent=create_permanent,
venueTypeCode=VenueTypeCode.MOVIE,
venueLabelId=venue_label_a.id,
collectiveOffers=(
[educational_factories.CollectiveOfferFactory(isActive=True)] if create_collective_offer else []
),
adageId="12345" if create_collective_offer else None,
collectiveOffers=collective_offers,
collectiveOfferTemplates=(
[educational_factories.CollectiveOfferTemplateFactory(isActive=True)] if create_template_offer else []
),
Expand Down Expand Up @@ -222,7 +239,9 @@ def test_update_external_pro_user_attributes(
venueTypeCode=VenueTypeCode.CONCERT_HALL, # different from others
)

with assert_num_queries(EXPECTED_PRO_ATTR_NUM_QUERIES):
num_queries = EXPECTED_PRO_ATTR_NUM_QUERIES

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je ne vois aucun test qui vérifie la valeur collectée de l'attribut eac_meg, il serait utile de vérifier que la logique est bonne, qu'elle soit exécutée en Python ou par postgreSQL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est vrai, je vais intégrer cela

with assert_num_queries(num_queries):
attributes = get_pro_attributes(email)

assert attributes.is_pro is True
Expand Down Expand Up @@ -272,6 +291,7 @@ def test_update_external_pro_user_attributes(
assert attributes.has_bookings is create_booking
assert attributes.has_collective_offers == (create_collective_offer or create_template_offer)
assert attributes.has_offers == (create_individual_offer or create_collective_offer or create_template_offer)
assert attributes.is_eac_meg == create_collective_offer_meg


def test_update_external_pro_user_attributes_no_offerer_no_venue():
Expand Down Expand Up @@ -336,7 +356,7 @@ def test_update_external_pro_booking_email_attributes():
venueTypeCode=VenueTypeCode.MUSEUM,
)

with assert_num_queries(4):
with assert_num_queries(5):
attributes = get_pro_attributes(email)

assert attributes.is_pro is True
Expand Down Expand Up @@ -382,7 +402,7 @@ def test_update_external_pro_booking_email_attributes_for_permanent_venue_with_b
_bannerUrl="https://example.net/banner.jpg",
)

with assert_num_queries(4):
with assert_num_queries(5):
attributes = get_pro_attributes(email)
assert attributes.isPermanent is True
assert attributes.has_banner_url is True
Expand All @@ -403,7 +423,7 @@ def test_update_external_pro_booking_email_attributes_for_non_permanent_venue_wi
_bannerUrl="https://example.net/banner.jpg",
)

with assert_num_queries(4):
with assert_num_queries(5):
attributes = get_pro_attributes(email)
assert attributes.isPermanent is False
assert attributes.has_banner_url is True
Expand All @@ -423,15 +443,16 @@ def test_update_external_pro_booking_email_attributes_for_non_permanent_venue_wi
venueTypeCode=VenueTypeCode.MUSEUM,
)

with assert_num_queries(4):
with assert_num_queries(5):
attributes = get_pro_attributes(email)
assert attributes.isPermanent is False
assert attributes.has_banner_url is True


def test_update_external_pro_removed_email_attributes():
# only 2 queries: user and venue - nothing found
with assert_num_queries(2):
# one query for marseille_en_grand
with assert_num_queries(3):
attributes = get_pro_attributes("[email protected]")

assert attributes.is_pro is True
Expand Down
10 changes: 6 additions & 4 deletions api/tests/core/external/sendinblue_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def test_format_attributes(self):
"VENUE_NAME": None,
"VENUE_TYPE": None,
"IS_EAC": None,
"EAC_MEG": None,
}

def test_format_pro_attributes(self):
Expand Down Expand Up @@ -156,6 +157,7 @@ def test_format_pro_attributes(self):
"VENUE_NAME": "Venue Name 1,Venue Name 2",
"VENUE_TYPE": "BOOKSTORE,MOVIE",
"IS_EAC": False,
"EAC_MEG": False,
}


Expand Down Expand Up @@ -216,10 +218,10 @@ def setup_method(self):
),
]

self.expected_header = "BOOKED_OFFER_CATEGORIES;BOOKED_OFFER_CATEGORIES_COUNT;BOOKED_OFFER_SUBCATEGORIES;BOOKING_COUNT;BOOKING_VENUES_COUNT;CREDIT;DATE_CREATED;DATE_OF_BIRTH;DEPARTMENT_CODE;DEPOSITS_COUNT;DEPOSIT_ACTIVATION_DATE;DEPOSIT_EXPIRATION_DATE;DMS_APPLICATION_APPROVED;DMS_APPLICATION_SUBMITTED;ELIGIBILITY;FIRSTNAME;HAS_BANNER_URL;HAS_BOOKINGS;HAS_COLLECTIVE_OFFERS;HAS_COMPLETED_ID_CHECK;HAS_OFFERS;INITIAL_CREDIT;IS_ACTIVE_PRO;IS_BENEFICIARY;IS_BENEFICIARY_18;IS_BOOKING_EMAIL;IS_CURRENT_BENEFICIARY;IS_EAC;IS_ELIGIBLE;IS_EMAIL_VALIDATED;IS_FORMER_BENEFICIARY;IS_PERMANENT;IS_PRO;IS_TAGGED_COLLECTIVITE;IS_UNDERAGE_BENEFICIARY;IS_USER_EMAIL;IS_VIRTUAL;LASTNAME;LAST_BOOKING_DATE;LAST_FAVORITE_CREATION_DATE;LAST_VISIT_DATE;MARKETING_EMAIL_SUBSCRIPTION;MOST_BOOKED_MOVIE_GENRE;MOST_BOOKED_MUSIC_TYPE;MOST_BOOKED_OFFER_SUBCATEGORY;MOST_FAVORITE_OFFER_SUBCATEGORIES;OFFERER_NAME;PERMANENT_THEME_PREFERENCE;POSTAL_CODE;PRODUCT_BRUT_X_USE_DATE;USER_ID;USER_IS_ATTACHED;USER_IS_CREATOR;VENUE_COUNT;VENUE_LABEL;VENUE_NAME;VENUE_TYPE;EMAIL"
self.eren_expected_file_body = "CINEMA,LIVRE;2;ABO_LIVRE_NUMERIQUE,CARTE_CINE_ILLIMITE,CINE_PLEIN_AIR;4;3;480.00;06-02-2021;06-05-2003;12;1;;;;;age-18;First name;;;;Yes;;500;;Yes;Yes;;Yes;;Yes;Yes;No;;No;;No;;;Last name;06-05-2021;;;Yes;COMEDY;900;CINE_PLEIN_AIR;CINE_PLEIN_AIR,SUPPORT_PHYSIQUE_FILM;;cinema;;06-05-2021;1;;;;;;;[email protected]"
self.mikasa_expected_file_body = "CINEMA,LIVRE;2;ABO_LIVRE_NUMERIQUE,CARTE_CINE_ILLIMITE,CINE_PLEIN_AIR;4;3;480.00;06-02-2021;06-05-2003;12;1;;;;;age-18;First name;;;Yes;Yes;;500;;Yes;Yes;;Yes;;Yes;Yes;No;;Yes;;No;;;Last name;06-05-2021;;;Yes;COMEDY;900;CINE_PLEIN_AIR;CINE_PLEIN_AIR,SUPPORT_PHYSIQUE_FILM;;cinema;;06-05-2021;2;;;;;;;[email protected]"
self.armin_expected_file_body = "CINEMA,LIVRE;2;ABO_LIVRE_NUMERIQUE,CARTE_CINE_ILLIMITE,CINE_PLEIN_AIR;4;3;480.00;06-02-2021;06-05-2003;12;1;;;;;age-18;First name;;;;Yes;;500;;Yes;Yes;;Yes;;Yes;Yes;No;;No;;No;;;Last name;06-05-2021;;;Yes;COMEDY;900;CINE_PLEIN_AIR;CINE_PLEIN_AIR,SUPPORT_PHYSIQUE_FILM;;cinema;;06-05-2021;3;;;;;;;[email protected]"
self.expected_header = "BOOKED_OFFER_CATEGORIES;BOOKED_OFFER_CATEGORIES_COUNT;BOOKED_OFFER_SUBCATEGORIES;BOOKING_COUNT;BOOKING_VENUES_COUNT;CREDIT;DATE_CREATED;DATE_OF_BIRTH;DEPARTMENT_CODE;DEPOSITS_COUNT;DEPOSIT_ACTIVATION_DATE;DEPOSIT_EXPIRATION_DATE;DMS_APPLICATION_APPROVED;DMS_APPLICATION_SUBMITTED;EAC_MEG;ELIGIBILITY;FIRSTNAME;HAS_BANNER_URL;HAS_BOOKINGS;HAS_COLLECTIVE_OFFERS;HAS_COMPLETED_ID_CHECK;HAS_OFFERS;INITIAL_CREDIT;IS_ACTIVE_PRO;IS_BENEFICIARY;IS_BENEFICIARY_18;IS_BOOKING_EMAIL;IS_CURRENT_BENEFICIARY;IS_EAC;IS_ELIGIBLE;IS_EMAIL_VALIDATED;IS_FORMER_BENEFICIARY;IS_PERMANENT;IS_PRO;IS_TAGGED_COLLECTIVITE;IS_UNDERAGE_BENEFICIARY;IS_USER_EMAIL;IS_VIRTUAL;LASTNAME;LAST_BOOKING_DATE;LAST_FAVORITE_CREATION_DATE;LAST_VISIT_DATE;MARKETING_EMAIL_SUBSCRIPTION;MOST_BOOKED_MOVIE_GENRE;MOST_BOOKED_MUSIC_TYPE;MOST_BOOKED_OFFER_SUBCATEGORY;MOST_FAVORITE_OFFER_SUBCATEGORIES;OFFERER_NAME;PERMANENT_THEME_PREFERENCE;POSTAL_CODE;PRODUCT_BRUT_X_USE_DATE;USER_ID;USER_IS_ATTACHED;USER_IS_CREATOR;VENUE_COUNT;VENUE_LABEL;VENUE_NAME;VENUE_TYPE;EMAIL"
self.eren_expected_file_body = "CINEMA,LIVRE;2;ABO_LIVRE_NUMERIQUE,CARTE_CINE_ILLIMITE,CINE_PLEIN_AIR;4;3;480.00;06-02-2021;06-05-2003;12;1;;;;;;age-18;First name;;;;Yes;;500;;Yes;Yes;;Yes;;Yes;Yes;No;;No;;No;;;Last name;06-05-2021;;;Yes;COMEDY;900;CINE_PLEIN_AIR;CINE_PLEIN_AIR,SUPPORT_PHYSIQUE_FILM;;cinema;;06-05-2021;1;;;;;;;[email protected]"
self.mikasa_expected_file_body = "CINEMA,LIVRE;2;ABO_LIVRE_NUMERIQUE,CARTE_CINE_ILLIMITE,CINE_PLEIN_AIR;4;3;480.00;06-02-2021;06-05-2003;12;1;;;;;;age-18;First name;;;Yes;Yes;;500;;Yes;Yes;;Yes;;Yes;Yes;No;;Yes;;No;;;Last name;06-05-2021;;;Yes;COMEDY;900;CINE_PLEIN_AIR;CINE_PLEIN_AIR,SUPPORT_PHYSIQUE_FILM;;cinema;;06-05-2021;2;;;;;;;[email protected]"
self.armin_expected_file_body = "CINEMA,LIVRE;2;ABO_LIVRE_NUMERIQUE,CARTE_CINE_ILLIMITE,CINE_PLEIN_AIR;4;3;480.00;06-02-2021;06-05-2003;12;1;;;;;;age-18;First name;;;;Yes;;500;;Yes;Yes;;Yes;;Yes;Yes;No;;No;;No;;;Last name;06-05-2021;;;Yes;COMEDY;900;CINE_PLEIN_AIR;CINE_PLEIN_AIR,SUPPORT_PHYSIQUE_FILM;;cinema;;06-05-2021;3;;;;;;;[email protected]"

def test_build_file_body(self):
expected = (
Expand Down
Loading
Loading