fiscalapi 4.0.450__tar.gz → 4.0.462__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {fiscalapi-4.0.450/fiscalapi.egg-info → fiscalapi-4.0.462}/PKG-INFO +7 -1
  2. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/README.md +6 -0
  3. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/models/ticket_models.py +2 -2
  4. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/base_service.py +3 -0
  5. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/invoice_service.py +11 -3
  6. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/stamp_service.py +11 -3
  7. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/ticket_service.py +6 -6
  8. {fiscalapi-4.0.450 → fiscalapi-4.0.462/fiscalapi.egg-info}/PKG-INFO +7 -1
  9. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi.egg-info/SOURCES.txt +1 -0
  10. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/setup.py +1 -1
  11. fiscalapi-4.0.462/tests/test_idempotency_key.py +87 -0
  12. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/tests/test_ticket_service.py +6 -7
  13. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/LICENSE.txt +0 -0
  14. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/MANIFEST.in +0 -0
  15. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/__init__.py +0 -0
  16. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/models/__init__.py +0 -0
  17. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/models/carta_porte_models.py +0 -0
  18. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/models/comercio_exterior_models.py +0 -0
  19. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/models/common_models.py +0 -0
  20. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/models/fiscalapi_models.py +0 -0
  21. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/models/manifest_models.py +0 -0
  22. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/models/sat_validation_models.py +0 -0
  23. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/models/webhook_models.py +0 -0
  24. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/py.typed +0 -0
  25. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/__init__.py +0 -0
  26. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/api_key_service.py +0 -0
  27. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/catalog_service.py +0 -0
  28. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/download_catalog_service.py +0 -0
  29. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/download_request_service.py +0 -0
  30. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/download_rule_service.py +0 -0
  31. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/employee_service.py +0 -0
  32. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/employer_service.py +0 -0
  33. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/fiscalapi_client.py +0 -0
  34. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/manifest_service.py +0 -0
  35. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/people_service.py +0 -0
  36. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/product_service.py +0 -0
  37. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/sat_validation_service.py +0 -0
  38. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/services/tax_file_service.py +0 -0
  39. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi/webhooks.py +0 -0
  40. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi.egg-info/dependency_links.txt +0 -0
  41. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi.egg-info/requires.txt +0 -0
  42. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/fiscalapi.egg-info/top_level.txt +0 -0
  43. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/pyproject.toml +0 -0
  44. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/setup.cfg +0 -0
  45. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/tests/test_cycle_contract.py +0 -0
  46. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/tests/test_error_trace_identifier.py +0 -0
  47. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/tests/test_invoice_item_ticket_id.py +0 -0
  48. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/tests/test_response_tolerance.py +0 -0
  49. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/tests/test_webhook_back_interop.py +0 -0
  50. {fiscalapi-4.0.450 → fiscalapi-4.0.462}/tests/test_webhook_verify.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fiscalapi
3
- Version: 4.0.450
3
+ Version: 4.0.462
4
4
  Summary: Genera facturas CFDI válidas ante el SAT consumiendo el API de https://www.fiscalapi.com
5
5
  Home-page: https://www.fiscalapi.com
6
6
  Author: Fiscalapi
@@ -284,6 +284,12 @@ invoice = Invoice(
284
284
  api_response = client.invoices.create(invoice)
285
285
  ```
286
286
 
287
+ Para reintentar la creación sin duplicar la factura, pasa una `idempotency_key` propia (hasta 64 caracteres). El SDK la envía como header `Idempotency-Key`; repetir la misma llave de idempotencia con la misma factura en 24 h devuelve la respuesta original:
288
+
289
+ ```python
290
+ api_response = client.invoices.create(invoice, idempotency_key="550e8400-e29b-41d4-a716-446655440000")
291
+ ```
292
+
287
293
  ### 6. Crear la Misma Factura de Ingreso (Por Valores)
288
294
 
289
295
  ```python
@@ -247,6 +247,12 @@ invoice = Invoice(
247
247
  api_response = client.invoices.create(invoice)
248
248
  ```
249
249
 
250
+ Para reintentar la creación sin duplicar la factura, pasa una `idempotency_key` propia (hasta 64 caracteres). El SDK la envía como header `Idempotency-Key`; repetir la misma llave de idempotencia con la misma factura en 24 h devuelve la respuesta original:
251
+
252
+ ```python
253
+ api_response = client.invoices.create(invoice, idempotency_key="550e8400-e29b-41d4-a716-446655440000")
254
+ ```
255
+
250
256
  ### 6. Crear la Misma Factura de Ingreso (Por Valores)
251
257
 
252
258
  ```python
@@ -132,8 +132,8 @@ class Ticket(BaseModel):
132
132
 
133
133
 
134
134
  class TicketIngestionResult(BaseModel):
135
- """Respuesta de ``tickets.create``: la misma forma en el 201 de un ticket nuevo y en el 200 de una repetición con la
136
- misma Idempotency-Key y el mismo cuerpo."""
135
+ """Respuesta de ``tickets.create``: un ticket nuevo (201) y la repetición con la misma llave de idempotencia y el mismo
136
+ cuerpo devuelven la misma respuesta original."""
137
137
 
138
138
  id: Optional[str] = Field(default=None, alias="id", description="Id del ticket.")
139
139
  ticket_code: Optional[str] = Field(default=None, alias="ticketCode", description="Código sin guiones, como lo lleva el QR; se imprime en grupos (XXXX-XXXX-XXXX).")
@@ -8,6 +8,9 @@ from fiscalapi.models.common_models import ApiResponse, FiscalApiSettings, Valid
8
8
 
9
9
  T = TypeVar('T')
10
10
 
11
+ # Header que el integrador usa para reintentar una petición sin duplicarla (crear factura, timbres y tickets).
12
+ IDEMPOTENCY_KEY_HEADER = "Idempotency-Key"
13
+
11
14
 
12
15
  class BaseService:
13
16
  def __init__(self, settings: FiscalApiSettings):
@@ -1,3 +1,5 @@
1
+ from typing import Optional
2
+
1
3
  from fiscalapi.models.common_models import ApiResponse, PagedList
2
4
  from fiscalapi.models.fiscalapi_models import (
3
5
  CancelInvoiceRequest,
@@ -9,7 +11,7 @@ from fiscalapi.models.fiscalapi_models import (
9
11
  InvoiceStatusResponse,
10
12
  SendInvoiceRequest,
11
13
  )
12
- from fiscalapi.services.base_service import BaseService
14
+ from fiscalapi.services.base_service import IDEMPOTENCY_KEY_HEADER, BaseService
13
15
 
14
16
 
15
17
  class InvoiceService(BaseService):
@@ -25,7 +27,7 @@ class InvoiceService(BaseService):
25
27
  endpoint = f"invoices/{invoice_id}"
26
28
  return self.send_request("GET", endpoint, Invoice, details=details)
27
29
 
28
- def create(self, invoice: Invoice) -> ApiResponse[Invoice]:
30
+ def create(self, invoice: Invoice, idempotency_key: Optional[str] = None) -> ApiResponse[Invoice]:
29
31
  """
30
32
  Crea una nueva factura CFDI.
31
33
 
@@ -36,14 +38,20 @@ class InvoiceService(BaseService):
36
38
  - 'N': Nómina
37
39
  - 'T': Traslado
38
40
 
41
+ Con idempotency_key (hasta 64 caracteres ASCII visibles, sin espacios) se envía el header Idempotency-Key:
42
+ repetir la llave de idempotencia con la misma petición en 24 h devuelve la respuesta original; con otra petición
43
+ responde 422, y mientras la original sigue en proceso, 409. Sin llave de idempotencia el header no se envía.
44
+
39
45
  Args:
40
46
  invoice: Modelo de factura con los datos requeridos.
47
+ idempotency_key: Valor del header Idempotency-Key, o None para no enviarlo.
41
48
 
42
49
  Returns:
43
50
  ApiResponse con la factura creada y timbrada.
44
51
  """
45
52
  endpoint = "invoices"
46
- return self.send_request("POST", endpoint, Invoice, payload=invoice)
53
+ headers = {} if idempotency_key is None else {IDEMPOTENCY_KEY_HEADER: idempotency_key}
54
+ return self.send_request("POST", endpoint, Invoice, payload=invoice, headers=headers)
47
55
 
48
56
  def cancel(self, cancel_invoice_request: CancelInvoiceRequest) -> ApiResponse[CancelInvoiceResponse]:
49
57
  """Cancela una factura."""
@@ -1,5 +1,7 @@
1
1
  """Servicio para gestionar transacciones de timbres (stamps)."""
2
2
 
3
+ from typing import Optional
4
+
3
5
  from fiscalapi.models import (
4
6
  ApiResponse,
5
7
  FiscalApiSettings,
@@ -7,7 +9,7 @@ from fiscalapi.models import (
7
9
  StampTransaction,
8
10
  StampTransactionParams,
9
11
  )
10
- from fiscalapi.services.base_service import BaseService
12
+ from fiscalapi.services.base_service import IDEMPOTENCY_KEY_HEADER, BaseService
11
13
 
12
14
 
13
15
  class StampService(BaseService):
@@ -41,20 +43,26 @@ class StampService(BaseService):
41
43
  endpoint = f"stamps/{transaction_id}"
42
44
  return self.send_request("GET", endpoint, StampTransaction)
43
45
 
44
- def transfer_stamps(self, request: StampTransactionParams) -> ApiResponse[bool]:
46
+ def transfer_stamps(self, request: StampTransactionParams, idempotency_key: Optional[str] = None) -> ApiResponse[bool]:
45
47
  """Transfer stamps or validation credits from one person to another.
46
48
 
47
49
  Use ``request.credit_type`` to pick which balance moves: ``CreditType.STAMP`` (default) moves
48
50
  stamps, ``CreditType.VALIDATION`` moves SAT validation credits. The two balances never mix.
49
51
 
52
+ With ``idempotency_key`` (up to 64 visible ASCII characters, no spaces) the ``Idempotency-Key`` header is
53
+ sent: repeating the idempotency key with the same transfer within 24 hours answers the original response; with another
54
+ transfer, 422; while the original is still in progress, 409. Without it the header is not sent.
55
+
50
56
  Args:
51
57
  request: StampTransactionParams containing transfer details.
58
+ idempotency_key: Value of the Idempotency-Key header, or None to not send it.
52
59
 
53
60
  Returns:
54
61
  ApiResponse containing a boolean indicating success.
55
62
  """
56
63
  endpoint = "stamps"
57
- return self.send_request("POST", endpoint, bool, payload=request)
64
+ headers = {} if idempotency_key is None else {IDEMPOTENCY_KEY_HEADER: idempotency_key}
65
+ return self.send_request("POST", endpoint, bool, payload=request, headers=headers)
58
66
 
59
67
  def withdraw_stamps(self, request: StampTransactionParams) -> ApiResponse[bool]:
60
68
  """Withdraw stamps or validation credits from a person.
@@ -5,9 +5,7 @@ from urllib.parse import urlencode
5
5
 
6
6
  from fiscalapi.models.common_models import ApiResponse, PagedList
7
7
  from fiscalapi.models.ticket_models import Ticket, TicketCodeResult, TicketIngestionResult, TicketListFilters
8
- from fiscalapi.services.base_service import BaseService
9
-
10
- IDEMPOTENCY_KEY_HEADER = "Idempotency-Key"
8
+ from fiscalapi.services.base_service import IDEMPOTENCY_KEY_HEADER, BaseService
11
9
 
12
10
 
13
11
  class TicketService(BaseService):
@@ -16,9 +14,11 @@ class TicketService(BaseService):
16
14
  def create(self, ticket: Ticket, idempotency_key: Optional[str] = None) -> ApiResponse[TicketIngestionResult]:
17
15
  """Ingest a ticket and charge 1 ticket credit. POST /api/v4/tickets
18
16
 
19
- With ``idempotency_key`` (up to 64 characters) the ``Idempotency-Key`` header is sent: repeating the key with
20
- the same body answers 200 with the original ticket without charging again; with another body, 422. Without it
21
- the header is not sent. An active folio and series of the issuer answers 409.
17
+ With ``idempotency_key`` (1 to 64 visible ASCII characters, no spaces) the ``Idempotency-Key`` header is sent:
18
+ repeating the same idempotency key with the same body, within 24 hours, returns the original response (201, with
19
+ the ``Idempotent-Replayed: true`` header) without registering another ticket or charging again; with another
20
+ body, 422; with the original still in progress, 409 with Retry-After. Without a key the header is not sent. An
21
+ active folio and series of the issuer answers 409.
22
22
 
23
23
  Args:
24
24
  ticket: Ticket to ingest.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fiscalapi
3
- Version: 4.0.450
3
+ Version: 4.0.462
4
4
  Summary: Genera facturas CFDI válidas ante el SAT consumiendo el API de https://www.fiscalapi.com
5
5
  Home-page: https://www.fiscalapi.com
6
6
  Author: Fiscalapi
@@ -284,6 +284,12 @@ invoice = Invoice(
284
284
  api_response = client.invoices.create(invoice)
285
285
  ```
286
286
 
287
+ Para reintentar la creación sin duplicar la factura, pasa una `idempotency_key` propia (hasta 64 caracteres). El SDK la envía como header `Idempotency-Key`; repetir la misma llave de idempotencia con la misma factura en 24 h devuelve la respuesta original:
288
+
289
+ ```python
290
+ api_response = client.invoices.create(invoice, idempotency_key="550e8400-e29b-41d4-a716-446655440000")
291
+ ```
292
+
287
293
  ### 6. Crear la Misma Factura de Ingreso (Por Valores)
288
294
 
289
295
  ```python
@@ -40,6 +40,7 @@ fiscalapi/services/tax_file_service.py
40
40
  fiscalapi/services/ticket_service.py
41
41
  tests/test_cycle_contract.py
42
42
  tests/test_error_trace_identifier.py
43
+ tests/test_idempotency_key.py
43
44
  tests/test_invoice_item_ticket_id.py
44
45
  tests/test_response_tolerance.py
45
46
  tests/test_ticket_service.py
@@ -2,7 +2,7 @@
2
2
  import os
3
3
  from setuptools import setup, find_packages
4
4
 
5
- VERSION = "4.0.450"
5
+ VERSION = "4.0.462"
6
6
 
7
7
  DESCRIPTION = "Genera facturas CFDI válidas ante el SAT consumiendo el API de https://www.fiscalapi.com"
8
8
 
@@ -0,0 +1,87 @@
1
+ """Llave de idempotencia opcional en crear factura y transferir timbres.
2
+
3
+ Con ``idempotency_key`` el SDK manda el header ``Idempotency-Key`` con ese valor, y sin ella no manda el header. La llave de idempotencia
4
+ no cambia el cuerpo de la petición. El SDK no genera ni reintenta la llave de idempotencia: solo la pasa.
5
+ """
6
+ from fiscalapi import Invoice, InvoiceIssuer, StampTransactionParams
7
+
8
+ INVOICES_URL = "https://sdk-tests.fiscalapi.invalid/api/v4/invoices"
9
+ STAMPS_URL = "https://sdk-tests.fiscalapi.invalid/api/v4/stamps"
10
+ ISSUER_ID = "4b1c2d3e-0000-4000-8000-000000000002"
11
+ PERSON_ID = "96b46762-d246-4a67-a562-510a25dbafa9"
12
+ IDEMPOTENCY_KEY = "pos-01-F-1001"
13
+
14
+ CREATED_INVOICE = {"succeeded": True, "message": "OK", "data": {"id": "7c1d2e3f-0000-4000-8000-0000000000b2"}}
15
+ TRANSFERRED = {"succeeded": True, "message": "OK", "data": True}
16
+
17
+
18
+ def _invoice() -> Invoice:
19
+ return Invoice(version_code="4.0", series="F", type_code="I", issuer=InvoiceIssuer(id=ISSUER_ID))
20
+
21
+
22
+ def _transfer() -> StampTransactionParams:
23
+ return StampTransactionParams(from_person_id=ISSUER_ID, to_person_id=PERSON_ID, amount=10)
24
+
25
+
26
+ # Crear factura
27
+
28
+ def test_create_invoice_sends_the_idempotency_key_header(client, fake_api):
29
+ fake_api.respond_with(CREATED_INVOICE)
30
+
31
+ client.invoices.create(_invoice(), idempotency_key=IDEMPOTENCY_KEY)
32
+
33
+ [request] = fake_api.requests
34
+ assert request["method"] == "POST"
35
+ assert request["url"] == INVOICES_URL
36
+ assert request["headers"]["Idempotency-Key"] == IDEMPOTENCY_KEY
37
+
38
+
39
+ def test_create_invoice_without_a_key_does_not_send_the_header(client, fake_api):
40
+ fake_api.respond_with(CREATED_INVOICE)
41
+
42
+ client.invoices.create(_invoice())
43
+
44
+ [request] = fake_api.requests
45
+ assert "Idempotency-Key" not in request["headers"]
46
+
47
+
48
+ def test_create_invoice_key_does_not_change_the_body(client, fake_api):
49
+ fake_api.respond_with(CREATED_INVOICE)
50
+
51
+ client.invoices.create(_invoice())
52
+ client.invoices.create(_invoice(), idempotency_key=IDEMPOTENCY_KEY)
53
+
54
+ without_key, with_key = fake_api.requests
55
+ assert with_key["json"] == without_key["json"]
56
+
57
+
58
+ # Transferir timbres
59
+
60
+ def test_transfer_stamps_sends_the_idempotency_key_header(client, fake_api):
61
+ fake_api.respond_with(TRANSFERRED)
62
+
63
+ client.stamps.transfer_stamps(_transfer(), idempotency_key=IDEMPOTENCY_KEY)
64
+
65
+ [request] = fake_api.requests
66
+ assert request["method"] == "POST"
67
+ assert request["url"] == STAMPS_URL
68
+ assert request["headers"]["Idempotency-Key"] == IDEMPOTENCY_KEY
69
+
70
+
71
+ def test_transfer_stamps_without_a_key_does_not_send_the_header(client, fake_api):
72
+ fake_api.respond_with(TRANSFERRED)
73
+
74
+ client.stamps.transfer_stamps(_transfer())
75
+
76
+ [request] = fake_api.requests
77
+ assert "Idempotency-Key" not in request["headers"]
78
+
79
+
80
+ def test_transfer_stamps_key_does_not_change_the_body(client, fake_api):
81
+ fake_api.respond_with(TRANSFERRED)
82
+
83
+ client.stamps.transfer_stamps(_transfer())
84
+ client.stamps.transfer_stamps(_transfer(), idempotency_key=IDEMPOTENCY_KEY)
85
+
86
+ without_key, with_key = fake_api.requests
87
+ assert with_key["json"] == without_key["json"]
@@ -1,7 +1,7 @@
1
1
  """Servicio de tickets de Auto CFDI (POST/GET/DELETE /api/v4/tickets).
2
2
 
3
3
  Los mismos escenarios viven en los SDK de .NET, Node.js, PHP y Java: el cuerpo exacto de la ingesta y el header
4
- Idempotency-Key solo si se pasa; las respuestas 201 y 200 de la ingesta; el 409 y el 422 con la forma de error del SDK
4
+ Idempotency-Key solo si se pasa; la respuesta 201 de la ingesta; el 409 y el 422 con la forma de error del SDK
5
5
  (``details`` con el texto del API y ``data`` en None); la query de la lista con ``status`` repetido; el detalle con y sin
6
6
  ``details``; el código; la cancelación con DELETE, y un estado que el SDK no conoce, conservado como texto.
7
7
  """
@@ -26,7 +26,7 @@ BASE_URL = "https://sdk-tests.fiscalapi.invalid/api/v4/tickets"
26
26
  ISSUER_ID = "4b1c2d3e-0000-4000-8000-000000000002"
27
27
  TICKET_ID = "9f8e7d6c-0000-4000-8000-0000000000a1"
28
28
  GLOBAL_INVOICE_ID = "7c1d2e3f-0000-4000-8000-0000000000b2"
29
- IDEMPOTENCY_KEY = "pos-01-F-1001"
29
+ IDEMPOTENCY_KEY = "550e8400-e29b-41d4-a716-446655440000"
30
30
 
31
31
  INGESTED = {
32
32
  "id": TICKET_ID,
@@ -158,16 +158,15 @@ def test_create_without_a_key_does_not_send_the_idempotency_key_header(client, f
158
158
  assert "Idempotency-Key" not in request["headers"]
159
159
 
160
160
 
161
- # b. Respuestas de la ingesta
161
+ # b. Respuesta de la ingesta: la repetición con la misma llave de idempotencia devuelve esta misma 201
162
162
 
163
- @pytest.mark.parametrize("status_code", [201, 200])
164
- def test_create_reads_the_new_ticket_and_the_idempotent_replay_with_the_same_shape(client, fake_api, status_code):
165
- fake_api.respond_with(_ok(INGESTED, status_code), status_code=status_code)
163
+ def test_create_reads_the_new_ticket_with_its_shape(client, fake_api):
164
+ fake_api.respond_with(_ok(INGESTED, 201), status_code=201)
166
165
 
167
166
  response = client.tickets.create(_new_ticket(), IDEMPOTENCY_KEY)
168
167
 
169
168
  assert response.succeeded is True
170
- assert response.http_status_code == status_code
169
+ assert response.http_status_code == 201
171
170
  assert response.error_data is None
172
171
  ingested = response.data
173
172
  assert ingested.id == TICKET_ID
File without changes
File without changes
File without changes
File without changes