"...documentation/nmaas-docs.git" did not exist on "3ac8949968e5ff8628c5f356546199d969bd0fc8"
Select Git revision
conftest.py 7.67 KiB
import itertools
import json
import re
from unittest.mock import patch
import pytest
import responses
from django.conf import settings
from django.contrib.auth import get_user_model
from django.test import Client
from django.utils import timezone
from stripe_checkout import config
from stripe_checkout.stripe_checkout import visit
from stripe_checkout.stripe_checkout.models import ExchangeRate, ItemKind, PricedItem
from stripe_checkout.stripe_checkout.visit import Visitor
User = get_user_model()
@pytest.fixture
def uses_db(request):
result = any(m.name == "django_db" for m in request.node.own_markers)
if result:
request.getfixturevalue("db") # ensure db is loaded
return result
@pytest.fixture
def user():
return User.objects.create_user("username", password="password")
@pytest.fixture
def item_data():
return [
dict(
name="side-meeting-friday",
display_name="Side Meeting Friday",
kind=ItemKind.EXTRA,
stripe_product_id="side-meeting-friday-stripe",
visit_checkout_question_id="side_meeting_checkout",
visit_checkout_answer_id="friday",
visit_paid_question_id="side_meeting_paid",
visit_paid_answer_id="friday-paid",
),
dict(
name="side-meeting-monday",
display_name="Side Meeting Monday",
kind=ItemKind.EXTRA,
stripe_product_id="side-meeting-monday-stripe",
visit_checkout_question_id="side_meeting_checkout",
visit_checkout_answer_id="monday",
visit_paid_question_id="side_meeting_paid",
visit_paid_answer_id="monday-paid",
),
dict(
name="participant",
display_name="Participant",
kind=ItemKind.REGISTRATION_TYPE,
visit_registration_id="participant",
stripe_product_id="participant-stripe",
),
]
@pytest.fixture(autouse=True)
def setup_django(uses_db, item_data, config_file):
config.load_config(config_file, settings)
if not uses_db:
return
for item in item_data:
PricedItem.objects.create(**item)
@pytest.fixture
def create_visitor(mock_visit):
ids = itertools.count()
def _create_visitor(registration_type=None, deleted=False, organization=None):
visitor_id = f"visitor{next(ids)}"
payload = {
"id": visitor_id,
"deleted": deleted,
"registrationType": {
"id": registration_type or "participant",
"name": registration_type or "Participant",
},
"contact": {
"firstName": "Some",
"lastName": "Visitor",
"email": f"{visitor_id}@example.com",
"addresses": [
{
"type": "billing",
"country": "NL",
}
],
},
"tags": [],
}
if organization is not None:
payload["questions"] = [
{
"id": visit.VISIT_ORGANIZATION_QUESTION_ID,
"answers": [{"value": "some_organization"}],
}
]
visitor = Visitor.from_api(payload)
mock_visit.append(visitor)
return visitor
return _create_visitor
@pytest.fixture
def mock_visit():
ALL_VISITORS = []
def list_visitors_callback(request):
return 200, {}, json.dumps(ALL_VISITORS)
responses.add_callback(
responses.GET,
re.compile(r"https://api.visitcloud.com/create/v2/visitors/[^/]+$"),
callback=list_visitors_callback,
content_type="application/json",
)
def _get_visitor(request):
visitors_by_id = {v["id"]: v for v in ALL_VISITORS if not v.get("deleted")}
match = re.search(r"/visitors/([^/]+)/([^/]+)", request.url)
_ = match.group(1) # expo_id ... maybe we can check this in the future
visitor_id = match.group(2)
return visitors_by_id[visitor_id]
def visitor_details_callback(request):
return 200, {}, json.dumps(_get_visitor(request))
def update_visitor_callback(request):
visitor = _get_visitor(request)
payload = json.loads(request.body)
payload["questions"] = _merge_questions(
visitor.get("questions", []), payload.get("questions", [])
)
visitor.update(payload)
return 200, {}, json.dumps(visitor)
responses.add_callback(
responses.GET,
re.compile(r"https://api.visitcloud.com/create/v2/visitors/[^/]+/[^/]+$"),
callback=visitor_details_callback,
content_type="application/json",
)
responses.add_callback(
responses.PUT,
re.compile(r"https://api.visitcloud.com/create/v2/visitors/[^/]+/[^/]+$"),
callback=update_visitor_callback,
content_type="application/json",
)
return ALL_VISITORS
def _merge_questions(current_questions, new_questions):
merged = {
**{question["id"]: question for question in current_questions},
**{question["id"]: question for question in new_questions},
}
return list(merged.values())
@pytest.fixture
def mock_stripe(item_data):
product_list = [
{"id": item["stripe_product_id"], "default_price": item["stripe_product_id"]}
for item in item_data
]
price_list = [
{"id": item["stripe_product_id"], "unit_amount": 1000} for item in item_data
]
with (
patch(
"stripe.Customer.search", return_value={"data": [{"id": "stripe-cus-id"}]}
),
patch("stripe.Customer.create", return_value={"id": "stripe-cus-id"}),
patch("stripe.Customer.modify", return_value={"id": "stripe-cus-id"}),
patch("stripe.Invoice.create", return_value={"id": "stripe-inv-id"}),
patch("stripe.Invoice.retrieve", return_value={"id": "stripe-inv-id"}),
patch("stripe.InvoiceItem.create", return_value={"id": "stripe-invitem-id"}),
patch(
"stripe.Invoice.send_invoice",
return_value={
"id": "inv_stripe-inv-id",
"hosted_invoice_url": "http://boguspath",
"payment_intent": "pi_some_payment_intent",
},
),
patch("stripe.Invoice.add_lines"),
patch("stripe.Price.list", return_value={"data": price_list}),
patch("stripe.Product.list", return_value={"data": product_list}),
):
yield
@pytest.fixture(autouse=True)
def mocked_apis(mock_visit, mock_stripe):
pass
@pytest.fixture
def default_visitor(create_visitor):
return create_visitor()
@pytest.fixture
def visitor_id(default_visitor):
return default_visitor["id"]
@pytest.fixture
def stripe_api_key():
return "api key xyz"
@pytest.fixture
def visit_api_key():
return "api-key"
@pytest.fixture
def visit_expo_id():
return "visit-expo-id"
@pytest.fixture
def config_file(stripe_api_key, visit_api_key, visit_expo_id, tmp_path):
file = tmp_path / "config.json"
file.write_text(
json.dumps(
{
"VISIT_API_KEY": visit_api_key,
"VISIT_EXPO_ID": visit_expo_id,
"STRIPE_API_KEY": stripe_api_key,
"STRIPE_SIGNING_SECRET": "stripe-signing-secret",
"STRIPE_INVOICE_TEMPLATE_ID": "stripe-invoice-template-id",
"STRIPE_TAX_RATE_ID": "stripe-tax-rate-id",
"SEND_ERROR_EMAILS_TO": ["test@geant.org"],
}
)
)
return file
@pytest.fixture
def client(mock_visit, mock_stripe):
return Client()
@pytest.fixture
def default_exchange_rate():
return ExchangeRate.objects.create(date=timezone.now().date(), rate=0.8)