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)