-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Closed
Labels
bugSomething isn't workingSomething isn't workingfixesRelated to suggested fixes for violationsRelated to suggested fixes for violations
Description
Fixing a rule creates a syntax error as of Ruff 0.15 (still an issue in 0.15.1)
Rule code RUF102
ruff.toml:
line-length = 99
target-version = "py311"
output-format = "grouped"
extend-exclude = [".uv-cache"]
[format]
quote-style = "single"
[lint]
allowed-confusables = ["‘", "’", "×", "–"]
select = ["ALL"]
ignore = [
# General configuration (see https://www.chasefinch.com/nitpick-style.toml)
"D203", "D213", "TID252", "S101", "INT001", # Rule conflicts
"COM812", "ISC001", "Q000", "Q003", # Recommended when using formatter
"RUF100", # Conflicts with WPS
"ARG", # Unused arguments often required in heirarchy
"ERA", # Commented-out code is OK
"S105", "S106", # Don't sniff for secrets
"S311", # Random is OK. Don't use them for "cryptographic purpses"
"S308", # Mark safe is OK
"S610", # Django "extra" is OK
"E731", "B023", # Lambda & unbound lambda is OK
"B024", # Allow ABCs without abstract methods
"BLE001", # Allow catching bare exception explicitly
"FIX002", "TD003", # Allow fully-formed TODOs
# Temporary exclusions
"G", "EM", "TRY", # Log formatting
"PT", # Test conventions (Use a regular `assert` instead of unittest-style `assertIn`)
"RUF012", # Typing convention (Mutable class attributes should be annotated with `typing.ClassVar`)
"DTZ", # Timezone enforcement ignored while we use naive datetimes
"FLY002", # String joins avoided
"PERF401", # Prefer list joins
"ANN", # No type annotation stuff yet
"D", "DOC", # No docstring requirements stuff yet
"S108", "S113", "S202", "S301", "S603", "S607", "S611", "SIM115", # Security notices
"PLW2901", # For loop target assignment
"PLC0415", # Inline imports, awaiting cleanup
# BringFido-specific opt-outs
"SLF", # Private member access
"PTH", # Path conventions
"CPY", # Copyright text
"C", "PLR09", # Complexity rules
"PLR2004" # Magic values
]
[lint.isort]
combine-as-imports = true
detect-same-package = true
section-order = [
"future",
"standard-library",
"third-party",
"django",
"first-party",
"local-folder"
]
known-first-party = ["google_"]
known-third-party = ["google"]
order-by-type = true
[lint.isort.sections]
django = ["django"]
[lint.per-file-ignores]
# General configuration
# Accept imports, strings & magic numbers generated by Django. Allow Django-style migration naming. Also ignore errors (DJ01) that are enforced at the model definition.
"*/migrations/*" = ["RUF012", "E501", "DJ01"]
# Temporary exclusions
# Allow __all__ until we can reorganize things
"*/admin.py" = ["DJ007"]
"*/forms.py" = ["DJ007"]
# BringFido-specific opt-outs
# Allow print in scripts & secrets, and secrets' module name
"scripts/*" = ["T201"]
".claude/*" = ["T201"]
"utilities/secrets.py" = ["A005", "T201"]
# Allow common module names in `common` and `utilities`
"common/*" = ["A005"]
"utilities/*" = ["A005"]
Offending code:
from decimal import Decimal
from http import HTTPStatus
from unittest import mock
import responses
from django.core.exceptions import ImproperlyConfigured
from django.test import TestCase
from ..api import TEST_CARD_NUMBER, TEST_CARD_SECURITY_CODE, TEST_POSTAL_CODE
from ..create_sale import CreateSaleRequest, TransactionError
from ..models import Transaction
class CreateSaleRequestTest(TestCase):
is_live_test = True
maxDiff = 3000 # noqa: WPS115 (overriding config property)
static_kwargs = {
'first_name': 'John',
'last_name': 'Doe',
'email': 'john.doe@example.com',
'phone': '(864) 555-1234',
'payment_security_fields': {'security_code': TEST_CARD_SECURITY_CODE},
}
dummy_connexpay_data = {'test': 'data'}
def make_mock_card(self):
card = mock.Mock()
card.name = 'John Doe'
card.number = TEST_CARD_NUMBER
card.expiry_month = '04'
card.expiry_year = 2050
card.address_1 = '101 Mulberry Ln.'
card.address_2 = ''
card.city = 'Whoville'
card.state = None
card.country = 'US'
card.country_iso2 = 'US'
card.postal_code = TEST_POSTAL_CODE
card.make_connexpay_data = mock.Mock(return_value=self.dummy_connexpay_data)
return card
def setUp(self):
transaction = mock.Mock(spec=Transaction)
transaction.number = 'A1B2C3D4E5F6'
transaction.customer_id = 41296
transaction.code = None
transaction.amount = Decimal('250.00')
self.transaction = transaction
kwargs = {
'transaction': self.transaction,
'payment_method': self.make_mock_card(),
}
kwargs.update(self.static_kwargs)
self.example_request = CreateSaleRequest(**kwargs)
def test_init(self):
card = self.make_mock_card()
kwargs = {
'transaction': self.transaction,
'payment_method': card,
}
kwargs.update(self.static_kwargs)
example = CreateSaleRequest(**kwargs)
expected_body = {
'Amount': Decimal('250.00'),
'Card': self.dummy_connexpay_data,
'CustomerID': 41296,
'ConnexPayTransaction': {'ExpectedPayments': 1},
'DeviceGuid': 'f4e178ae-c66c-4ed8-ba0d-6be1ee0121ac',
'OrderNumber': 'A1B2C3D4E5F6',
'ProductType': 'BringFido',
'RiskData': {
'ProductType': 'Hotel',
'BillingAddress1': '101 Mulberry Ln.',
'BillingAddress2': '',
'BillingCity': 'Whoville',
'BillingCountryCode': 'US',
'BillingPhoneNumber': '(864) 555-1234',
'BillingPostalCode': TEST_POSTAL_CODE,
'Email': 'john.doe@example.com',
'Name': 'John Doe',
'OrderNumber': 'A1B2C3D4E5F6',
},
'RiskProcessingOnly': False,
'SendReceipt': False,
'StatementDescription': 'BringFido',
}
self.assertEqual(expected_body, example.body)
card.state = 'SC'
example = CreateSaleRequest(**kwargs)
self.assertEqual(example.body['RiskData']['BillingState'], card.state)
# Assert error with processed transaction
self.transaction.code = 'dummy'
with self.assertRaises(ImproperlyConfigured):
example = CreateSaleRequest(**kwargs)
@responses.activate(registry=responses.registries.OrderedRegistry)
@mock.patch('connexpay.api.Server.get_token')
def test_query(self, get_token):
# Set up mock data
dummy_token_string = 'qwerty-zxcvbn'
get_token.return_value = dummy_token_string
responses.add(
responses.POST,
self.example_request.url,
json={
'status': 'Transaction - Approved',
'test_key': 'test_response',
'guid': '1234-abcd',
'connexPayTransaction': {
'incomingTransCode': 'qwerty123',
},
},
status=HTTPStatus.OK,
)
# Assert error before registering a stay
with self.assertRaises(ImproperlyConfigured):
self.example_request.query()
# Assert success cases
test_hotel_id = 10101
self.example_request.register_stay(num_nights=3, hotel_id=test_hotel_id)
self.example_request.query()
# Assert HTTP error handling
responses.add(
responses.POST,
self.example_request.url,
json={'message': 'dummy'},
status=HTTPStatus.UNPROCESSABLE_ENTITY,
)
with self.assertRaises(ImproperlyConfigured):
self.example_request.query()
responses.add(
responses.POST,
self.example_request.url,
json={'status': 'Transaction - Declined'},
status=HTTPStatus.CREATED,
)
with self.assertRaises(TransactionError):
self.example_request.query()
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingfixesRelated to suggested fixes for violationsRelated to suggested fixes for violations