4.55.0
All checks were successful
Build-Release-Image / Build-Image (linux/amd64) (push) Successful in 3m43s
Build-Release-Image / Build-Image (linux/arm64) (push) Successful in 4m10s
Build-Release-Image / Merge-Images (push) Successful in 27s
Build-Release-Image / Create-Release (push) Successful in 10s
Build-Release-Image / Notify (push) Successful in 3s
All checks were successful
Build-Release-Image / Build-Image (linux/amd64) (push) Successful in 3m43s
Build-Release-Image / Build-Image (linux/arm64) (push) Successful in 4m10s
Build-Release-Image / Merge-Images (push) Successful in 27s
Build-Release-Image / Create-Release (push) Successful in 10s
Build-Release-Image / Notify (push) Successful in 3s
This commit is contained in:
54
app/tests/events/test_dead_letter_event_source.py
Normal file
54
app/tests/events/test_dead_letter_event_source.py
Normal file
@ -0,0 +1,54 @@
|
||||
import arrow
|
||||
|
||||
from app.db import Session
|
||||
from app.models import SyncEvent
|
||||
from events.event_source import DeadLetterEventSource, _DEAD_LETTER_THRESHOLD_MINUTES
|
||||
|
||||
|
||||
class EventCounter:
|
||||
def __init__(self):
|
||||
self.processed_events = 0
|
||||
|
||||
def on_event(self, event: SyncEvent):
|
||||
self.processed_events += 1
|
||||
|
||||
|
||||
def setup_function(func):
|
||||
Session.query(SyncEvent).delete()
|
||||
|
||||
|
||||
def test_dead_letter_does_not_take_untaken_events():
|
||||
source = DeadLetterEventSource(1)
|
||||
counter = EventCounter()
|
||||
threshold_time = arrow.utcnow().shift(minutes=-(_DEAD_LETTER_THRESHOLD_MINUTES) + 1)
|
||||
SyncEvent.create(
|
||||
content="test".encode("utf-8"), created_at=threshold_time, flush=True
|
||||
)
|
||||
SyncEvent.create(
|
||||
content="test".encode("utf-8"), taken_time=threshold_time, flush=True
|
||||
)
|
||||
events_processed = source.execute_loop(on_event=counter.on_event)
|
||||
assert len(events_processed) == 0
|
||||
assert counter.processed_events == 0
|
||||
|
||||
|
||||
def test_dead_letter_takes_untaken_events_created_older_than_threshold():
|
||||
source = DeadLetterEventSource(1)
|
||||
counter = EventCounter()
|
||||
old_create = arrow.utcnow().shift(minutes=-_DEAD_LETTER_THRESHOLD_MINUTES - 1)
|
||||
SyncEvent.create(content="test".encode("utf-8"), created_at=old_create, flush=True)
|
||||
events_processed = source.execute_loop(on_event=counter.on_event)
|
||||
assert len(events_processed) == 1
|
||||
assert events_processed[0].taken_time > old_create
|
||||
assert counter.processed_events == 1
|
||||
|
||||
|
||||
def test_dead_letter_takes_taken_events_created_older_than_threshold():
|
||||
source = DeadLetterEventSource(1)
|
||||
counter = EventCounter()
|
||||
old_taken = arrow.utcnow().shift(minutes=-_DEAD_LETTER_THRESHOLD_MINUTES - 1)
|
||||
SyncEvent.create(content="test".encode("utf-8"), taken_time=old_taken, flush=True)
|
||||
events_processed = source.execute_loop(on_event=counter.on_event)
|
||||
assert len(events_processed) == 1
|
||||
assert events_processed[0].taken_time > old_taken
|
||||
assert counter.processed_events == 1
|
||||
@ -1,7 +1,9 @@
|
||||
import arrow
|
||||
|
||||
from app import config, alias_utils
|
||||
from app.db import Session
|
||||
from app.events.event_dispatcher import GlobalDispatcher
|
||||
from app.models import Alias
|
||||
from app.models import Alias, SyncEvent
|
||||
from tests.utils import random_token
|
||||
from .event_test_utils import (
|
||||
OnMemoryDispatcher,
|
||||
@ -26,6 +28,33 @@ def setup_function(func):
|
||||
on_memory_dispatcher.clear()
|
||||
|
||||
|
||||
def test_event_taken_updates():
|
||||
event = SyncEvent.create(content="test".encode("utf-8"), flush=True)
|
||||
assert event.taken_time is None
|
||||
assert event.mark_as_taken()
|
||||
assert event.taken_time is not None
|
||||
|
||||
|
||||
def test_event_mark_as_taken_does_nothing_for_taken_events():
|
||||
now = arrow.utcnow()
|
||||
event = SyncEvent.create(content="test".encode("utf-8"), taken_time=now, flush=True)
|
||||
assert not event.mark_as_taken()
|
||||
|
||||
|
||||
def test_event_mark_as_taken_does_nothing_for_not_before_events():
|
||||
now = arrow.utcnow()
|
||||
event = SyncEvent.create(content="test".encode("utf-8"), taken_time=now, flush=True)
|
||||
older_than = now.shift(minutes=-1)
|
||||
assert not event.mark_as_taken(allow_taken_older_than=older_than)
|
||||
|
||||
|
||||
def test_event_mark_as_taken_works_for_before_events():
|
||||
now = arrow.utcnow()
|
||||
event = SyncEvent.create(content="test".encode("utf-8"), taken_time=now, flush=True)
|
||||
older_than = now.shift(minutes=+1)
|
||||
assert event.mark_as_taken(allow_taken_older_than=older_than)
|
||||
|
||||
|
||||
def test_fire_event_on_alias_creation():
|
||||
(user, pu) = _create_linked_user()
|
||||
alias = Alias.create_new_random(user)
|
||||
@ -79,7 +108,7 @@ def test_fire_event_on_alias_status_change():
|
||||
alias = Alias.create_new_random(user)
|
||||
Session.flush()
|
||||
on_memory_dispatcher.clear()
|
||||
alias_utils.change_alias_status(alias, True)
|
||||
alias_utils.change_alias_status(alias, enabled=True)
|
||||
assert len(on_memory_dispatcher.memory) == 1
|
||||
event_data = on_memory_dispatcher.memory[0]
|
||||
event_content = _get_event_from_string(event_data, user, pu)
|
||||
|
||||
109
app/tests/events/test_subscription_webhook.py
Normal file
109
app/tests/events/test_subscription_webhook.py
Normal file
@ -0,0 +1,109 @@
|
||||
import arrow
|
||||
|
||||
from app import config
|
||||
from app.events.event_dispatcher import GlobalDispatcher
|
||||
from app.events.generated.event_pb2 import UserPlanChanged
|
||||
from app.models import (
|
||||
Subscription,
|
||||
AppleSubscription,
|
||||
CoinbaseSubscription,
|
||||
ManualSubscription,
|
||||
User,
|
||||
PartnerUser,
|
||||
)
|
||||
|
||||
from .event_test_utils import (
|
||||
OnMemoryDispatcher,
|
||||
_create_linked_user,
|
||||
_get_event_from_string,
|
||||
)
|
||||
from tests.utils import random_token
|
||||
|
||||
from app.subscription_webhook import execute_subscription_webhook
|
||||
|
||||
|
||||
on_memory_dispatcher = OnMemoryDispatcher()
|
||||
|
||||
|
||||
def setup_module():
|
||||
GlobalDispatcher.set_dispatcher(on_memory_dispatcher)
|
||||
config.EVENT_WEBHOOK = "http://test"
|
||||
|
||||
|
||||
def teardown_module():
|
||||
GlobalDispatcher.set_dispatcher(None)
|
||||
config.EVENT_WEBHOOK = None
|
||||
|
||||
|
||||
def setup_function(func):
|
||||
on_memory_dispatcher.clear()
|
||||
|
||||
|
||||
def check_event(user: User, pu: PartnerUser) -> UserPlanChanged:
|
||||
assert len(on_memory_dispatcher.memory) == 1
|
||||
event_data = on_memory_dispatcher.memory[0]
|
||||
event_content = _get_event_from_string(event_data, user, pu)
|
||||
assert event_content.user_plan_change is not None
|
||||
plan_change = event_content.user_plan_change
|
||||
return plan_change
|
||||
|
||||
|
||||
def test_webhook_with_trial():
|
||||
(user, pu) = _create_linked_user()
|
||||
execute_subscription_webhook(user)
|
||||
assert check_event(user, pu).plan_end_time == 0
|
||||
|
||||
|
||||
def test_webhook_with_subscription():
|
||||
(user, pu) = _create_linked_user()
|
||||
end_at = arrow.utcnow().shift(days=1).replace(hour=0, minute=0, second=0)
|
||||
Subscription.create(
|
||||
user_id=user.id,
|
||||
cancel_url="",
|
||||
update_url="",
|
||||
subscription_id=random_token(10),
|
||||
event_time=arrow.now(),
|
||||
next_bill_date=end_at.date(),
|
||||
plan="yearly",
|
||||
flush=True,
|
||||
)
|
||||
execute_subscription_webhook(user)
|
||||
assert check_event(user, pu).plan_end_time == end_at.timestamp
|
||||
|
||||
|
||||
def test_webhook_with_apple_subscription():
|
||||
(user, pu) = _create_linked_user()
|
||||
end_at = arrow.utcnow().shift(days=2).replace(hour=0, minute=0, second=0)
|
||||
AppleSubscription.create(
|
||||
user_id=user.id,
|
||||
receipt_data=arrow.now().date().strftime("%Y-%m-%d"),
|
||||
expires_date=end_at.date().strftime("%Y-%m-%d"),
|
||||
original_transaction_id=random_token(10),
|
||||
plan="yearly",
|
||||
product_id="",
|
||||
flush=True,
|
||||
)
|
||||
execute_subscription_webhook(user)
|
||||
assert check_event(user, pu).plan_end_time == end_at.timestamp
|
||||
|
||||
|
||||
def test_webhook_with_coinbase_subscription():
|
||||
(user, pu) = _create_linked_user()
|
||||
end_at = arrow.utcnow().shift(days=3).replace(hour=0, minute=0, second=0)
|
||||
CoinbaseSubscription.create(
|
||||
user_id=user.id, end_at=end_at.date().strftime("%Y-%m-%d"), flush=True
|
||||
)
|
||||
|
||||
execute_subscription_webhook(user)
|
||||
assert check_event(user, pu).plan_end_time == end_at.timestamp
|
||||
|
||||
|
||||
def test_webhook_with_manual_subscription():
|
||||
(user, pu) = _create_linked_user()
|
||||
end_at = arrow.utcnow().shift(days=3).replace(hour=0, minute=0, second=0)
|
||||
ManualSubscription.create(
|
||||
user_id=user.id, end_at=end_at.date().strftime("%Y-%m-%d"), flush=True
|
||||
)
|
||||
|
||||
execute_subscription_webhook(user)
|
||||
assert check_event(user, pu).plan_end_time == end_at.timestamp
|
||||
Reference in New Issue
Block a user