From 08fe29620412151853a6d5763290c97bbd4108c8 Mon Sep 17 00:00:00 2001 From: Anatolii Vasilev Date: Wed, 28 Jan 2026 21:18:22 +0100 Subject: [PATCH] feat: get saved for later --- .../saved_for_later_operations.py | 99 +++++++++++++++ .../tests/test_graphql_get_saved_for_later.py | 119 ++++++++++++++++++ 2 files changed, 218 insertions(+) create mode 100644 graphql_operations/saved_for_later/saved_for_later_operations.py create mode 100644 tests_graphql/tests/test_graphql_get_saved_for_later.py diff --git a/graphql_operations/saved_for_later/saved_for_later_operations.py b/graphql_operations/saved_for_later/saved_for_later_operations.py new file mode 100644 index 0000000..5da0e07 --- /dev/null +++ b/graphql_operations/saved_for_later/saved_for_later_operations.py @@ -0,0 +1,99 @@ +from gql import Client + +from graphql_client.mutations.move_from_saved_for_later import ( + MoveFromSavedForLaterMutation, +) +from graphql_client.mutations.move_to_saved_for_later import MoveToSavedForLaterMutation +from graphql_client.mutations.remove_wishlist_item import RemoveWishlistItemMutation +from graphql_client.queries.get_saved_for_later import GetSavedForLaterQuery +from graphql_client.types.cart_type import CartType +from graphql_client.types.cart_with_list_type import CartWithListType +from graphql_client.types.input_remove_wishlist_item_type import ( + InputRemoveWishlistItemType, +) +from graphql_client.types.input_save_for_later_type import InputSaveForLaterType +from graphql_client.types.wishlist_type import WishlistType +from graphql_operations.cart.fragments.cart_fragment import CART_FRAGMENT + + +class SavedForLaterOperations: + def __init__(self, graphql_client: Client): + self.graphql_client = graphql_client + + def move_to_saved_for_later(self, payload: InputSaveForLaterType) -> CartWithListType: + move_to_saved_for_later_mutation = MoveToSavedForLaterMutation(self.graphql_client) + + variables = {"command": payload} + + return_fields = f""" + cart {{ + {CART_FRAGMENT} + }} + list {{ + {CART_FRAGMENT} + }} + """ + + result = move_to_saved_for_later_mutation.execute(variables=variables, return_fields=return_fields) + + return result + + def move_from_saved_for_later(self, payload: InputSaveForLaterType) -> CartWithListType: + move_from_saved_for_later_mutation = MoveFromSavedForLaterMutation(self.graphql_client) + + variables = {"command": payload} + + return_fields = f""" + cart {{ + {CART_FRAGMENT} + }} + list {{ + {CART_FRAGMENT} + }} + """ + + result = move_from_saved_for_later_mutation.execute(variables=variables, return_fields=return_fields) + + return result + + def get_saved_for_later( + self, + store_id: str, + user_id: str, + currency_code: str, + culture_name: str, + organization_id: str | None = None, + ) -> CartType: + get_saved_for_later_query = GetSavedForLaterQuery(self.graphql_client) + + variables = { + "storeId": store_id, + "userId": user_id, + "currencyCode": currency_code, + "cultureName": culture_name, + } + + if organization_id: + variables["organizationId"] = organization_id + + result = get_saved_for_later_query.execute(variables=variables, return_fields=CART_FRAGMENT) + + return result + + def remove_saved_for_later_item(self, payload: InputRemoveWishlistItemType) -> WishlistType: + """Remove item from saved for later list.""" + remove_wishlist_item_mutation = RemoveWishlistItemMutation(self.graphql_client) + + variables = {"command": payload} + + return_fields = """ + id + items { + id + productId + } + """ + + result = remove_wishlist_item_mutation.execute(variables=variables, return_fields=return_fields) + + return result diff --git a/tests_graphql/tests/test_graphql_get_saved_for_later.py b/tests_graphql/tests/test_graphql_get_saved_for_later.py new file mode 100644 index 0000000..a28d14c --- /dev/null +++ b/tests_graphql/tests/test_graphql_get_saved_for_later.py @@ -0,0 +1,119 @@ +import os +from typing import Any + +import allure +import pytest + +from fixtures.auth import Auth +from fixtures.config import Config +from fixtures.graphql_client import GraphQLClient +from graphql_operations.cart.cart_operations import CartOperations +from graphql_operations.saved_for_later.saved_for_later_operations import ( + SavedForLaterOperations, +) +from graphql_operations.user.user_operations import UserOperations + + +@pytest.mark.graphql +@allure.title("Get saved for later (GraphQL)") +def test_get_saved_for_later( + config: Config, + dataset: dict[str, Any], + graphql_client: GraphQLClient, + auth: Auth, +): + print(f"{os.linesep}Running test to get saved for later...", end=" ") + + user_operations = UserOperations(graphql_client) + cart_operations = CartOperations(graphql_client) + saved_for_later_operations = SavedForLaterOperations(graphql_client) + + currency = dataset["currencies"][0]["code"] + culture = dataset["languages"][0]["allowedValues"][0] + product_id = dataset["products"][2]["id"] # Use product that is in stock + + auth.authenticate( + dataset["users"][0]["userName"], + config["USERS_PASSWORD"], + ) + + user = user_operations.get_me() + + # Clean up any existing saved for later items + existing_saved_for_later = saved_for_later_operations.get_saved_for_later( + store_id=config["STORE_ID"], + user_id=user["id"], + currency_code=currency, + culture_name=culture, + ) + + if existing_saved_for_later and existing_saved_for_later["items"]: + for item in existing_saved_for_later["items"]: + saved_for_later_operations.remove_saved_for_later_item( + payload={ + "listId": existing_saved_for_later["id"], + "lineItemId": item["id"], + } + ) + + cart = cart_operations.add_item_to_cart( + payload={ + "storeId": config["STORE_ID"], + "userId": user["id"], + "productId": product_id, + "quantity": 1, + "currencyCode": currency, + "cultureName": culture, + } + ) + + line_item_id = cart["items"][0]["id"] + + move_result = saved_for_later_operations.move_to_saved_for_later( + payload={ + "storeId": config["STORE_ID"], + "userId": user["id"], + "cartId": cart["id"], + "lineItemIds": [line_item_id], + "currencyCode": currency, + "cultureName": culture, + } + ) + + # Get saved for later list + saved_for_later = saved_for_later_operations.get_saved_for_later( + store_id=config["STORE_ID"], + user_id=user["id"], + currency_code=currency, + culture_name=culture, + ) + + # Test teardown + saved_for_later_operations.remove_saved_for_later_item( + payload={ + "listId": saved_for_later["id"], + "lineItemId": saved_for_later["items"][0]["id"], + } + ) + + auth.clear_token() + + # Assertions + assert move_result is not None, "Move to saved for later result is None" + assert move_result["cart"] is not None, "Cart in move result is None" + assert move_result["list"] is not None, "List in move result is None" + + # Verify item was removed from cart + assert move_result["cart"]["itemsQuantity"] == 0, "Item should be removed from cart" + + # Verify item is in saved for later list + assert move_result["list"]["itemsQuantity"] == 1, "Item should be in saved for later list" + + # Verify getSavedForLater query returns the list + assert saved_for_later is not None, "Saved for later list is None" + assert saved_for_later["itemsQuantity"] == 1, "Saved for later should have 1 item" + + # Verify the correct product is in saved for later + saved_items = saved_for_later["items"] + assert len(saved_items) == 1, "Should have exactly 1 saved item" + assert saved_items[0]["productId"] == product_id, "Saved item product ID mismatch"