Skip to content

Commit

Permalink
New events related to gift card changes (#9588)
Browse files Browse the repository at this point in the history
* GiftCards webhook events

* Changes after review.

* GIFT_CARD_STATUS_CHANGED enum value fix

* Fix tests coverage

* Revert last commit

* Graphql schema update
  • Loading branch information
szdrasiak committed Apr 26, 2022
1 parent e5d78c6 commit 52adcd1
Show file tree
Hide file tree
Showing 22 changed files with 932 additions and 2 deletions.
21 changes: 21 additions & 0 deletions saleor/graphql/giftcard/bulk_mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import graphene
from django.core.exceptions import ValidationError
from django.db import transaction

from ...core.permissions import GiftcardPermissions
from ...core.tracing import traced_atomic_transaction
Expand Down Expand Up @@ -69,6 +70,10 @@ def perform_mutation(cls, _root, info, **data):
instances = cls.create_instances(input_data, info)
if tags:
cls.assign_gift_card_tags(instances, tags)

transaction.on_commit(
lambda: cls.call_gift_card_created_on_plugins(instances, info)
)
return cls(count=len(instances), gift_cards=instances)

@staticmethod
Expand Down Expand Up @@ -147,6 +152,11 @@ def assign_gift_card_tags(
for tag_instance in tags_instances.iterator():
tag_instance.gift_cards.set(instances)

@staticmethod
def call_gift_card_created_on_plugins(instances, info):
for instance in instances:
info.context.plugins.gift_card_created(instance)


class GiftCardBulkDelete(ModelBulkDeleteMutation):
class Arguments:
Expand All @@ -161,6 +171,13 @@ class Meta:
permissions = (GiftcardPermissions.MANAGE_GIFT_CARD,)
error_type_class = GiftCardError

@classmethod
def bulk_action(cls, info, queryset):
instances = [card for card in queryset]
queryset.delete()
for instance in instances:
info.context.plugins.gift_card_deleted(instance)


class GiftCardBulkActivate(BaseBulkMutation):
class Arguments:
Expand Down Expand Up @@ -192,6 +209,8 @@ def bulk_action(cls, info, queryset):
events.gift_cards_activated_event(
gift_card_ids, user=info.context.user, app=info.context.app
)
for card in models.GiftCard.objects.filter(id__in=gift_card_ids):
info.context.plugins.gift_card_status_changed(card)


class GiftCardBulkDeactivate(BaseBulkMutation):
Expand All @@ -218,3 +237,5 @@ def bulk_action(cls, info, queryset):
events.gift_cards_deactivated_event(
gift_card_ids, user=info.context.user, app=info.context.app
)
for card in models.GiftCard.objects.filter(id__in=gift_card_ids):
info.context.plugins.gift_card_status_changed(card)
9 changes: 9 additions & 0 deletions saleor/graphql/giftcard/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ def post_save_action(cls, info, instance, cleaned_input):
channel_slug=cleaned_input["channel"],
resending=False,
)
info.context.plugins.gift_card_created(instance)

@staticmethod
def assign_gift_card_tags(instance: models.GiftCard, tags_values: Iterable[str]):
Expand Down Expand Up @@ -338,6 +339,7 @@ def perform_mutation(cls, _root, info, **data):
if tags_updated:
events.gift_card_tags_updated_event(instance, old_tags, user, app)

info.context.plugins.gift_card_updated(instance)
return cls.success_response(instance)

@classmethod
Expand Down Expand Up @@ -373,6 +375,10 @@ class Meta:
error_type_class = GiftCardError
error_type_field = "gift_card_errors"

@classmethod
def post_save_action(cls, info, instance, cleaned_input):
info.context.plugins.gift_card_deleted(instance)


class GiftCardDeactivate(BaseMutation):
gift_card = graphene.Field(GiftCard, description="Deactivated gift card.")
Expand All @@ -399,6 +405,7 @@ def perform_mutation(cls, _root, info, **data):
events.gift_card_deactivated_event(
gift_card=gift_card, user=info.context.user, app=info.context.app
)
info.context.plugins.gift_card_status_changed(gift_card)
return GiftCardDeactivate(gift_card=gift_card)


Expand Down Expand Up @@ -428,6 +435,7 @@ def perform_mutation(cls, _root, info, **data):
events.gift_card_activated_event(
gift_card=gift_card, user=info.context.user, app=info.context.app
)
info.context.plugins.gift_card_status_changed(gift_card)
return GiftCardActivate(gift_card=gift_card)


Expand Down Expand Up @@ -556,4 +564,5 @@ def perform_mutation(cls, _root, info, **data):
app=info.context.app,
message=cleaned_input["message"],
)
info.context.plugins.gift_card_updated(gift_card)
return GiftCardAddNote(gift_card=gift_card, event=event)
50 changes: 50 additions & 0 deletions saleor/graphql/giftcard/tests/mutations/test_gift_card_activate.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from datetime import date, timedelta
from unittest import mock

import graphene
from django.utils.functional import SimpleLazyObject

from .....giftcard import GiftCardEvents
from .....giftcard.error_codes import GiftCardErrorCode
from .....webhook.event_types import WebhookEventAsyncType
from ....tests.utils import assert_no_permission, get_graphql_content

ACTIVATE_GIFT_CARD_MUTATION = """
Expand Down Expand Up @@ -179,3 +182,50 @@ def test_activate_expired_gift_card(
assert len(errors) == 1
assert errors[0]["field"] == "id"
assert errors[0]["code"] == GiftCardErrorCode.EXPIRED_GIFT_CARD.name


@mock.patch("saleor.plugins.webhook.plugin.get_webhooks_for_event")
@mock.patch("saleor.plugins.webhook.plugin.trigger_webhooks_async")
def test_activate_gift_card_trigger_webhook(
mocked_webhook_trigger,
mocked_get_webhooks_for_event,
any_webhook,
staff_api_client,
gift_card,
permission_manage_gift_card,
permission_manage_users,
permission_manage_apps,
settings,
):
# given
mocked_get_webhooks_for_event.return_value = [any_webhook]
settings.PLUGINS = ["saleor.plugins.webhook.plugin.WebhookPlugin"]

gift_card.is_active = False
gift_card.save(update_fields=["is_active"])
assert not gift_card.is_active
variables = {"id": graphene.Node.to_global_id("GiftCard", gift_card.id)}

# when
response = staff_api_client.post_graphql(
ACTIVATE_GIFT_CARD_MUTATION,
variables,
permissions=[
permission_manage_gift_card,
permission_manage_users,
permission_manage_apps,
],
)

# then
content = get_graphql_content(response)
data = content["data"]["giftCardActivate"]["giftCard"]
assert data["isActive"]

mocked_webhook_trigger.assert_called_once_with(
{"id": variables["id"], "is_active": True},
WebhookEventAsyncType.GIFT_CARD_STATUS_CHANGED,
[any_webhook],
gift_card,
SimpleLazyObject(lambda: staff_api_client.user),
)
53 changes: 53 additions & 0 deletions saleor/graphql/giftcard/tests/mutations/test_gift_card_add_note.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from datetime import date, timedelta
from unittest import mock

import graphene
import pytest
from django.utils.functional import SimpleLazyObject

from .....giftcard import GiftCardEvents
from .....giftcard.error_codes import GiftCardErrorCode
from .....webhook.event_types import WebhookEventAsyncType
from ....tests.utils import get_graphql_content

GIFT_CARD_ADD_NOTE_MUTATION = """
Expand Down Expand Up @@ -191,3 +194,53 @@ def test_gift_card_add_note_expired_card(
assert event.type == GiftCardEvents.NOTE_ADDED
assert event.user == staff_user
assert event.parameters == {"message": message}


@mock.patch("saleor.plugins.webhook.plugin.get_webhooks_for_event")
@mock.patch("saleor.plugins.webhook.plugin.trigger_webhooks_async")
def test_gift_card_add_note_trigger_webhook(
mocked_webhook_trigger,
mocked_get_webhooks_for_event,
any_webhook,
staff_api_client,
permission_manage_apps,
permission_manage_users,
permission_manage_gift_card,
gift_card,
staff_user,
settings,
):
# given
mocked_get_webhooks_for_event.return_value = [any_webhook]
settings.PLUGINS = ["saleor.plugins.webhook.plugin.WebhookPlugin"]

gift_card_id = graphene.Node.to_global_id("GiftCard", gift_card.id)
message = "nuclear note"
variables = {"id": gift_card_id, "message": message}

# when
response = staff_api_client.post_graphql(
GIFT_CARD_ADD_NOTE_MUTATION,
variables,
permissions=[
permission_manage_apps,
permission_manage_users,
permission_manage_gift_card,
],
)

# then
content = get_graphql_content(response)
data = content["data"]["giftCardAddNote"]
assert data["giftCard"]

mocked_webhook_trigger.assert_called_once_with(
{
"id": graphene.Node.to_global_id("GiftCard", gift_card.id),
"is_active": gift_card.is_active,
},
WebhookEventAsyncType.GIFT_CARD_UPDATED,
[any_webhook],
gift_card,
SimpleLazyObject(lambda: staff_api_client.user),
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import date, timedelta
from unittest import mock

import graphene

Expand Down Expand Up @@ -180,3 +181,42 @@ def test_gift_card_bulk_activate_expired_cards(
]
for error in errors:
assert error in expected_errors


@mock.patch("saleor.plugins.webhook.plugin.get_webhooks_for_event")
@mock.patch("saleor.plugins.webhook.plugin.trigger_webhooks_async")
def test_gift_card_bulk_activate_trigger_webhook(
mocked_webhook_trigger,
mocked_get_webhooks_for_event,
any_webhook,
staff_api_client,
gift_card,
gift_card_expiry_date,
permission_manage_gift_card,
settings,
):
# given
mocked_get_webhooks_for_event.return_value = [any_webhook]
settings.PLUGINS = ["saleor.plugins.webhook.plugin.WebhookPlugin"]

gift_card.is_active = False
gift_card_expiry_date.is_active = False
gift_cards = [gift_card, gift_card_expiry_date]
GiftCard.objects.bulk_update(gift_cards, ["is_active"])

ids = [graphene.Node.to_global_id("GiftCard", card.pk) for card in gift_cards]
variables = {"ids": ids}

# when
response = staff_api_client.post_graphql(
MUTATION_GIFT_CARD_BULK_ACTIVATE,
variables,
permissions=(permission_manage_gift_card,),
)

# then
content = get_graphql_content(response)
data = content["data"]["giftCardBulkActivate"]

assert data["count"] == len(ids)
assert mocked_webhook_trigger.call_count == len(ids)
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import date, timedelta
from unittest import mock

import pytest

Expand Down Expand Up @@ -161,6 +162,61 @@ def test_create_never_expiry_gift_cards(
assert not card_data["events"][0]["balance"]["oldCurrentBalance"]


@mock.patch("saleor.plugins.webhook.plugin.get_webhooks_for_event")
@mock.patch("saleor.plugins.webhook.plugin.trigger_webhooks_async")
def test_create_gift_cards_trigger_webhooks(
mocked_webhook_trigger,
mocked_get_webhooks_for_event,
any_webhook,
staff_api_client,
permission_manage_gift_card,
permission_manage_users,
permission_manage_apps,
settings,
):
# given
mocked_get_webhooks_for_event.return_value = [any_webhook]
settings.PLUGINS = ["saleor.plugins.webhook.plugin.WebhookPlugin"]

initial_balance = 100
currency = "USD"
tags = ["gift-card-tag", "gift-card-tag-2"]
count = 10
is_active = True
variables = {
"input": {
"count": count,
"balance": {
"amount": initial_balance,
"currency": currency,
},
"tags": tags,
"isActive": is_active,
}
}

# when
response = staff_api_client.post_graphql(
GIFT_CARD_BULK_CREATE_MUTATION,
variables,
permissions=[
permission_manage_gift_card,
permission_manage_users,
permission_manage_apps,
],
)

# then
content = get_graphql_content(response)
errors = content["data"]["giftCardBulkCreate"]["errors"]
data = content["data"]["giftCardBulkCreate"]

assert not errors
assert data["count"] == count
assert len(data["giftCards"]) == count
assert mocked_webhook_trigger.call_count == count


def test_create_gift_cards_with_expiry_date_by_app(
app_api_client,
permission_manage_gift_card,
Expand Down

0 comments on commit 52adcd1

Please sign in to comment.