test_product.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import os
  2. import pytest
  3. from asgi_csrf import asgi_csrf
  4. from fastapi.testclient import TestClient
  5. from lxml import html
  6. from starsessions import (
  7. CookieStore,
  8. SessionStore,
  9. )
  10. from app.main import app
  11. client = TestClient(app)
  12. @pytest.fixture
  13. def app_csrf():
  14. """Return a CSRF token."""
  15. return asgi_csrf(app, signing_secret=os.getenv("CSRF_SECRET_KEY"))
  16. @pytest.fixture()
  17. def session_store() -> SessionStore:
  18. """WIP."""
  19. return CookieStore(secret_key=os.getenv("SESSION_SECRET_KEY"))
  20. def prepare_request(product_id: str) -> tuple[dict[str, str], str]:
  21. """Machinery to get back a tuple with headers and a valid CSRF token
  22. to then use to send a POST request.
  23. """
  24. headers = {
  25. "Accept-Language": "en-US,en;q=0.5",
  26. "Referer": f"http://localhost:5014/products/{product_id}",
  27. }
  28. response_get = client.get(f"/products/{product_id}", headers=headers)
  29. tree = html.fromstring(response_get.content)
  30. csrf_token = tree.xpath("//input[@name='csrftoken']")[0].get("value")
  31. return (headers, csrf_token)
  32. def test_add_product(capsys, app_csrf, session_store):
  33. """Run tests for:
  34. - adding a product with no options (size, style), good
  35. - adding a product with no options, bad (wrong query, missing param)
  36. - adding a product with options, good
  37. - adding a product with options, bad (wrong options)
  38. - removing a product with no options (size, style), good
  39. - removing a product with no options, bad (wrong query, missing param)
  40. - removing a product with options, good
  41. - removing a product with options, bad (wrong options)
  42. - remove a product entirely using the remove button
  43. """
  44. # -- product with no options (size, style)
  45. headers_no_options, csrf_token_no_options = prepare_request("cap-01")
  46. data_good_no_options_add = {
  47. "page": "product",
  48. "operation": "add",
  49. "product_id": "stripe_product_abc",
  50. "product_path": "products/cap-01",
  51. "price": 30,
  52. "quantity": 2,
  53. "csrftoken": csrf_token_no_options,
  54. }
  55. response_good_no_options_add = client.post(
  56. "/checkout", data=data_good_no_options_add, headers=headers_no_options
  57. )
  58. with capsys.disabled():
  59. print(f"client => {client.cookies}")
  60. assert response_good_no_options_add.status_code == 200
  61. data_good_no_options_remove = {
  62. "page": "product",
  63. "operation": "remove",
  64. "product_id": "stripe_product_abc",
  65. "product_path": "products/cap-01",
  66. "price": 30,
  67. "quantity": 1,
  68. "csrftoken": csrf_token_no_options,
  69. }
  70. response_good_no_options_remove = client.post(
  71. "/checkout", data=data_good_no_options_remove, headers=headers_no_options
  72. )
  73. assert response_good_no_options_remove.status_code == 200
  74. # wrong options
  75. data_bad_no_options_wrong_add = {
  76. "page": "product",
  77. "product_id": "stripe_product_abc",
  78. "product_path": "products/cap-01",
  79. "price": 30,
  80. "size": None,
  81. "style": "black",
  82. "quantity": 2,
  83. "csrftoken": csrf_token_no_options,
  84. }
  85. response_bad_no_options_add = client.post(
  86. "/checkout", data=data_bad_no_options_wrong_add, headers=headers_no_options
  87. )
  88. assert response_bad_no_options_add.status_code == 422
  89. data_bad_no_options_wrong_remove = {
  90. "page": "product",
  91. "product_id": "stripe_product_abc",
  92. "product_path": "products/cap-01",
  93. "price": 30,
  94. "size": None,
  95. "style": "black",
  96. "quantity": 2,
  97. "csrftoken": csrf_token_no_options,
  98. }
  99. response_bad_no_options_remove = client.post(
  100. "/checkout", data=data_bad_no_options_wrong_remove, headers=headers_no_options
  101. )
  102. assert response_bad_no_options_remove.status_code == 422
  103. # -- product with options (size, style)
  104. headers_with_options, csrf_token_with_options = prepare_request("tshirt-darkfi")
  105. data_good_with_options_add = {
  106. "page": "product",
  107. "operation": "add",
  108. "product_id": "stripe_product_tshirt-df",
  109. "product_path": "products/tshirt-darkfi",
  110. "price": 50,
  111. "quantity": 3,
  112. "size": "m",
  113. "style": "black",
  114. "csrftoken": csrf_token_with_options,
  115. }
  116. response_good_with_options_add = client.post(
  117. "/checkout", data=data_good_with_options_add, headers=headers_with_options
  118. )
  119. assert response_good_with_options_add.status_code == 200
  120. data_good_with_options_remove = {
  121. "page": "product",
  122. "operation": "remove",
  123. "product_id": "stripe_product_tshirt-df",
  124. "product_path": "products/tshirt-darkfi",
  125. "price": 50,
  126. "quantity": 2,
  127. "size": "m",
  128. "style": "black",
  129. "csrftoken": csrf_token_with_options,
  130. }
  131. response_good_with_options_remove = client.post(
  132. "/checkout", data=data_good_with_options_remove, headers=headers_with_options
  133. )
  134. assert response_good_with_options_remove.status_code == 200
  135. # wrong options
  136. data_bad_with_options_wrong_add = {
  137. "page": "product",
  138. "operation": "add",
  139. "product_id": "stripe_product_tshirt-df",
  140. "product_path": "products/tshirt-darkfi",
  141. "price": 50,
  142. "quantity": 5,
  143. "size": "x",
  144. "style": "yellow",
  145. "csrftoken": csrf_token_with_options,
  146. }
  147. response_bad_with_options_add = client.post(
  148. "/checkout", data=data_bad_with_options_wrong_add, headers=headers_with_options
  149. )
  150. assert response_bad_with_options_add.status_code == 422
  151. data_bad_with_options_wrong_remove = {
  152. "page": "product",
  153. "operation": "remove",
  154. "product_id": "stripe_product_tshirt-df",
  155. "product_path": "products/tshirt-darkfi",
  156. "price": 50,
  157. "quantity": 5,
  158. "size": "x",
  159. "style": "yellow",
  160. "csrftoken": csrf_token_with_options,
  161. }
  162. response_bad_with_options_remove = client.post(
  163. "/checkout",
  164. data=data_bad_with_options_wrong_remove,
  165. headers=headers_with_options,
  166. )
  167. assert response_bad_with_options_remove.status_code == 422