Skip to content

Commit

Permalink
Merge branch 'saleor:main' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
iamleson98 authored Aug 25, 2024
2 parents b185783 + a76e77e commit ce8b012
Show file tree
Hide file tree
Showing 401 changed files with 25,883 additions and 4,631 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ services:
- ..:/app

dashboard:
image: ghcr.io/saleor/saleor-dashboard:3.20
image: ghcr.io/saleor/saleor-dashboard:3.20.5
restart: unless-stopped
ports:
- 9000:80
Expand Down
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ repos:
exclude_types: [svg]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.10
rev: v0.5.4
hooks:
- id: ruff
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.10.0
rev: v1.7.1
hooks:
- id: mypy
language: system
exclude: tests/

- repo: https://github.com/fpgmaas/deptry.git
rev: "0.16.1"
rev: "0.17.0"
hooks:
- id: deptry

Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@ All notable, unreleased changes to this project will be documented in this file.

### Breaking changes

- Drop the `manager.perform_mutation` method. - #16515 by @maarcingebala

### GraphQL API

- Add `CheckoutCustomerNoteUpdate` mutation - #16315 by @pitkes22

### Webhooks

### Other changes

- Added support for numeric and lower-case boolean environment variables - #16313 by @NyanKiyoshi
- Fixed a potential crash when Checkout metadata is accessed with high concurrency - #16411 by @patrys
- Add slugs to product/category/collection/page translations. Allow to query by translated slug - #16449 by @delemeator
- Fixed a crash when the Decimal scalar is passed a non-normal value - #16520 by @patrys
2 changes: 1 addition & 1 deletion conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
"saleor.graphql.order.tests.benchmark.fixtures",
"saleor.graphql.giftcard.tests.benchmark.fixtures",
"saleor.graphql.webhook.tests.benchmark.fixtures",
"saleor.plugins.webhook.tests.subscription_webhooks.fixtures",
"saleor.tax.tests.fixtures",
"saleor.webhook.tests.subscription_webhooks.fixtures",
]


Expand Down
1,378 changes: 717 additions & 661 deletions poetry.lock

Large diffs are not rendered by default.

26 changes: 12 additions & 14 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ documentation = "https://docs.saleor.io/"
cryptography = "^42.0.5"
dj-database-url = "^2"
dj-email-url = "^1"
django = {version = "^3.2.24", extras = ["bcrypt"]}
django = {version = "^4.2", extras = ["bcrypt"]}
django-cache-url = "^3.1.2"
django-celery-beat = "^2.2.1"
django-countries = "^7.2"
Expand All @@ -39,10 +39,9 @@ documentation = "https://docs.saleor.io/"
django-mptt = "^0"
django-phonenumber-field = ">=4,<8"
django-prices = "^2.3"
django-redis = "^5.0.0"
django-stubs-ext = "^4.2.1"
draftjs-sanitizer = "^1.0.0"
faker = ">=4.1,<24.0"
faker = ">=26.0.0,<27.0"
google-cloud-pubsub = ">=1.7,<3.0"
google-cloud-storage = "^2.0.0"
google-i18n-address = "^3.1.0"
Expand All @@ -63,10 +62,9 @@ documentation = "https://docs.saleor.io/"
phonenumberslite = "^8.12.25"
pillow = "^10.3.0"
pillow-avif-plugin = "^1.3.1"
posuto = "^2024.6.0"
posuto = "^2024.7.0"
prices = "^1.0"
promise = "^2.3"
psycopg2 = "^2.8.3"
pybars3 = "^0.9.7"
pyjwt = "2.5.0" # Version 2.6.0 changed iat validation which causes tests to fail: https://github.com/saleor/saleor/issues/11047
python-dateutil = "^2.8.2"
Expand All @@ -77,17 +75,18 @@ documentation = "https://docs.saleor.io/"
razorpay = "^1.2"
redis = "^5.0.1"
requests = "^2.32"
requests-hardened = "1.0.0b3"
requests-hardened = "1.0.0b4"
Rx = "^1.6.3"
semantic-version = "^2.10.0"
sendgrid = "^6.7.1"
sentry-sdk = "1.40.5" # https://github.com/getsentry/sentry-python/issues/2554
sentry-sdk = "^2.12"
stripe = "^3.0.0"
text-unidecode = "^1.2"
urllib3 = "^1.26.19"
uvicorn = {extras = ["standard"], version = "^0.23.1"}
weasyprint = ">=53.0" # libpango >=1.44 is required
setuptools = "^70.1.0"
psycopg = {version = "^3.1.8", extras = ["binary"]}

[tool.poetry.dependencies.celery]
version = ">=4.4.5,<6.0.0"
Expand All @@ -108,22 +107,21 @@ documentation = "https://docs.saleor.io/"
[tool.poetry.group.dev.dependencies]
before_after = "^1.0.1"
coverage = "^7.2"
deptry = "^0.12.0"
deptry = "^0.17.0"
django-debug-toolbar = "^4.0"
django-debug-toolbar-request-history = "^0"
django-graphiql-debug-toolbar = "^0.2.0"
django-extensions = "^3.1.2"
django-stubs = "^4.2.6"
django-stubs = { version = "^4.2.7", extras = ["compatible-mypy"] }
fakeredis = "^2.10"
freezegun = "^1"
mypy = "1.10.0"
mypy-extensions = "^1.0.0"
openpyxl = "^3.0.3"
openpyxl = "^3.1.5"
pre-commit = "^3.4"
pytest = "^8.0.0"
pytest-asyncio = "^0.23.7"
pytest-celery = "^0.0.0"
pytest-cov = "^4.0.0"
pytest-cov = "^5.0.0"
pytest-django = "4.8.0"
pytest-django-queries = "~1.2"
pytest-memray = "^1.5.0"
Expand All @@ -132,7 +130,7 @@ documentation = "https://docs.saleor.io/"
pytest-socket = "^0.7.0"
pytest-xdist = "^3.0.2"
pywatchman = "^2.0.0"
ruff = "^0.4.9"
ruff = "^0.5.4"
semgrep = ">=1.34.0"
types-certifi = "^2021.10.8"
types-freezegun = "^1.1.7"
Expand All @@ -155,7 +153,7 @@ extend_exclude = ["conftest\\.py", ".*/conftest\\.py", ".*/tests/.*"]

[tool.deptry.per_rule_ignores]
DEP001 = ["pkg_resources"]
DEP002 = ["azure-common", "azure-storage-blob", "azure-storage-common", "django-redis", "gunicorn", "psycopg2"]
DEP002 = ["azure-common", "azure-storage-blob", "azure-storage-common", "gunicorn", "psycopg"]
DEP004 = ["debug_toolbar", "graphiql_debug_toolbar"]

[tool.ruff]
Expand Down
3 changes: 0 additions & 3 deletions saleor/account/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
default_app_config = "saleor.account.app.AccountAppConfig"


class CustomerEvents:
"""The different customer event types."""

Expand Down
File renamed without changes.
6 changes: 4 additions & 2 deletions saleor/account/i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

COUNTRY_FORMS = {}
UNKNOWN_COUNTRIES = set()
ADDRESS_FIELDS_TO_LOG = ["country_area", "city_area", "city", "postal_code"]
ADDRESS_FIELDS_TO_LOG = ["country_area", "city_area", "city"]

AREA_TYPE = {
"area": "Area",
Expand Down Expand Up @@ -211,13 +211,15 @@ def substitute_invalid_values(data):
data[field_name] = mapping[actual_value]

def log_errors(self):
if not self.data.get("skip_validation"):
return

errors = self.errors
fields = {}
for field, _ in errors.items():
fields[field] = (
self.data.get(field) if field in ADDRESS_FIELDS_TO_LOG else "invalid"
)
fields["skip_validation"] = self.data.get("skip_validation")
fields["country"] = self.data.get("country")
logger.warning("Invalid address input: %s", fields)

Expand Down
34 changes: 34 additions & 0 deletions saleor/account/migrations/0086_auto_20240805_0851.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions saleor/account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,16 @@ class Meta:
fields=["private_metadata"],
opclasses=["jsonb_path_ops"],
),
GinIndex(
fields=["first_name"],
name="first_name_gin",
opclasses=["gin_trgm_ops"],
),
GinIndex(
fields=["last_name"],
name="last_name_gin",
opclasses=["gin_trgm_ops"],
),
]

def __init__(self, *args, **kwargs):
Expand Down
1 change: 0 additions & 1 deletion saleor/app/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
default_app_config = "saleor.app.app.AppConfig"
2 changes: 2 additions & 0 deletions saleor/app/installation_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from .. import schema_version
from ..app.headers import AppHeaders, DeprecatedAppHeaders
from ..celeryconf import app
from ..core.db.connection import allow_writer
from ..core.http_client import HTTPClient
from ..core.utils import build_absolute_uri, get_domain
from ..permission.enums import get_permission_names
Expand Down Expand Up @@ -150,6 +151,7 @@ def _set_brand_data(brand_obj: Optional[Union[App, AppInstallation]], logo: File


@app.task(bind=True, retry_backoff=2700, retry_kwargs={"max_retries": 5})
@allow_writer()
def fetch_brand_data_task(
self, brand_data: dict, *, app_installation_id=None, app_id=None
):
Expand Down
7 changes: 5 additions & 2 deletions saleor/app/manifest_validations.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,11 @@ def clean_manifest_data(manifest_data, raise_for_saleor_version=False):
app_permissions = []

manifest_data["permissions"] = app_permissions

if app := App.objects.filter(identifier=manifest_data.get("id")).first():
if (
app := App.objects.not_removed()
.filter(identifier=manifest_data.get("id"))
.first()
):
errors["identifier"].append(
ValidationError(
f"App with the same identifier is already installed: {app.name}"
Expand Down
6 changes: 6 additions & 0 deletions saleor/app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ def for_event_type(self, event_type: str):
**permissions,
)

def not_removed(self):
return self.filter(removed_at__isnull=True)

def marked_to_be_removed(self):
return self.filter(removed_at__isnull=False)


AppManager = models.Manager.from_queryset(AppQueryset)

Expand Down
15 changes: 12 additions & 3 deletions saleor/app/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

from .. import celeryconf
from ..core import JobStatus
from ..core.db.connection import allow_writer
from ..core.models import EventDelivery, EventDeliveryAttempt, EventPayload
from ..core.tasks import delete_files_from_private_storage_task
from ..webhook.models import Webhook
from .installation_utils import AppInstallationError, install_app
from .models import App, AppExtension, AppInstallation, AppToken
Expand All @@ -17,6 +19,7 @@


@celeryconf.app.task
@allow_writer()
def install_app_task(job_id, activate=False):
try:
app_installation = AppInstallation.objects.get(id=job_id)
Expand Down Expand Up @@ -70,12 +73,21 @@ def _raw_remove_deliveries(deliveries_ids):
attempts = EventDeliveryAttempt.objects.filter(
Exists(deliveries.filter(id=OuterRef("delivery_id")))
)

files_to_delete = [
event_payload.payload_file.name
for event_payload in payloads.using(settings.DATABASE_CONNECTION_REPLICA_NAME)
if event_payload.payload_file
]
delete_files_from_private_storage_task.delay(files_to_delete)

attempts._raw_delete(attempts.db) # type: ignore[attr-defined] # raw access # noqa: E501
deliveries._raw_delete(deliveries.db) # type: ignore[attr-defined] # raw access # noqa: E501
payloads._raw_delete(payloads.db) # type: ignore[attr-defined] # raw access # noqa: E501


@celeryconf.app.task
@allow_writer()
def remove_apps_task():
app_delete_period = timezone.now() - settings.DELETE_APP_TTL
apps = App.objects.filter(removed_at__lte=app_delete_period)
Expand Down Expand Up @@ -106,9 +118,6 @@ def remove_apps_task():
_raw_remove_deliveries(deliveries_ids)

webhooks.delete()

AppToken.objects.filter(app_id=app.id).delete()

AppExtension.objects.filter(app_id=app.id).delete()

app.delete()
11 changes: 8 additions & 3 deletions saleor/app/tests/test_app_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from requests import RequestException
from requests_hardened import HTTPSession

from ...core import JobStatus
from ...core import JobStatus, private_storage
from ...core.models import EventDelivery, EventDeliveryAttempt, EventPayload
from ...webhook.models import Webhook
from ..installation_utils import AppInstallationError
Expand Down Expand Up @@ -114,7 +114,10 @@ def test_install_app_task_undefined_error(monkeypatch, app_installation):
# Without `transaction=True` test will pass due to be in one atomic bloc.
@pytest.mark.django_db(transaction=True)
def test_remove_app_task(
event_attempt_removed_app, removed_app_with_extensions, removed_app
event_attempt_removed_app,
event_payload,
removed_app_with_extensions,
removed_app,
):
# given
removed_app.tokens.create(name="token1")
Expand All @@ -125,6 +128,7 @@ def test_remove_app_task(
assert EventDelivery.objects.count() > 0
assert EventPayload.objects.count() > 0
assert EventDeliveryAttempt.objects.count() > 0
assert private_storage.exists(event_payload.payload_file.name)

# when
remove_apps_task()
Expand All @@ -137,13 +141,14 @@ def test_remove_app_task(
assert EventDelivery.objects.count() == 0
assert EventPayload.objects.count() == 0
assert EventDeliveryAttempt.objects.count() == 0
assert not private_storage.exists(event_payload.payload_file.name)


def test_remove_app_task_not_remove_not_own_payloads(
event_attempt_removed_app,
):
# given
EventPayload.objects.create(payload="")
EventPayload.objects.create()
assert EventPayload.objects.count() == 2

# when
Expand Down
2 changes: 1 addition & 1 deletion saleor/celeryconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def setup_celery_logging(loglevel=None, **kwargs):

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "saleor.settings")

app = Celery("saleor")
app = Celery("saleor", task_cls="saleor.core.tasks:RestrictWriterDBTask")

app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()
Expand Down
Loading

0 comments on commit ce8b012

Please sign in to comment.