mirror of
https://github.com/Second-Hand-Friends/kleinanzeigen-bot.git
synced 2026-07-09 20:51:05 +02:00
b5e2769f2d3d18b3fb579d534336fde0b50be47e
11 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b5e2769f2d |
refactor: extract special attribute helpers from publishing form (#1161)
## ℹ️ Description Extract three module-level helpers from `set_special_attributes()` in `publishing_form.py` to reduce local variable count and improve readability. `set_special_attributes` had 27 locals — after extraction it has 10. - Behavior-preserving: no change to exception propagation, logging, or control flow. - `condition_s` probe stays in main to avoid translation-key churn. ## 📋 Changes Summary - Extract `_build_special_attribute_xpath()` — Pure XPath construction (fix comment: five → six patterns) - Extract `_resolve_special_attribute_element()` — Wraps `web_find_all` + candidate pick, propagates exceptions uncaught - Extract `_set_special_attribute_input()` — 6-branch input-type dispatch; hidden-input returns without logging, caller logs once - Rewire `set_special_attributes` to call the three helpers - Ratchet `pyproject.toml`: PLR0914 max-locals 27 → 20 - Update `translations.de.yaml`: move 4 debug messages + add `Failed to set attribute` under `_set_special_attribute_input` ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) - [x] ♻️ Refactor (non-breaking restructuring of existing code) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). → 1268 passed, 4 skipped - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. → Translation file updated <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Chores** * Tightened linting rules by lowering the allowed maximum number of local variables. * **Refactor** * Reworked special-attribute DOM handling to use clearer selection and value-setting paths for different field types, including improved fallback behavior. * **Tests** * Added async unit test coverage for `set_special_attributes`, including input fallback behavior and error cases for unsupported checkbox values and missing hidden input metadata. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d384f172b8 |
fix: remove individual shipping publishing (#1159)
## ℹ️ Description - Link to the related issue(s): Issue #1157 - Kleinanzeigen no longer offers individual/custom shipping. This updates publishing, validation, docs, schemas, translations, and tests so existing `shipping_costs` configs are handled gracefully instead of failing against removed DOM controls. ## 📋 Changes Summary - Keep `shipping_costs` for legacy configs/downloaded ads, but mark it deprecated in schema/docs and ignore it during publishing. - Remove publishing interaction with removed individual-shipping DOM controls. - Require predefined non-empty `shipping_options` for `sell_directly`. - Update docs, generated schemas/config artifacts, German translations, and unit tests. - Verified live DOM for `sell_directly: true` + `shipping_type: SHIPPING` + predefined `shipping_options` via local ignored script; no ad submission performed. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [x] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Updated shipping guides to deprecate custom individual shipping costs and make publishing depend on per-ad predefined `shipping_options` (DHL/Hermes; selectable options must come from a single size group). * Added migration guidance replacing `shipping_costs` with the correct `shipping_options`. * Clarified “Sell directly” requires `shipping_type: SHIPPING`, non-empty `shipping_options`, and `FIXED`/`NEGOTIABLE` pricing. * **Bug Fixes** * Publishing is blocked when `shipping_costs` is provided without `shipping_options`. * Removed unsupported individual-shipping handling and tightened “Sell directly” eligibility rules. * **Tests** * Expanded unit coverage for deprecation behavior, content handling, and direct-buy validation. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
801ed0e223 |
refactor: remove KleinanzeigenBot re-export from package root (#1150)
## ℹ️ Description - Link to the related issue(s): N/A - Removes the unsupported package-root `KleinanzeigenBot` re-export after tests were moved to their owning modules. - Updates remaining tests and `conftest.py` to import `KleinanzeigenBot` from `kleinanzeigen_bot.app` directly. - Re-enables Ruff's mccabe complexity checks and tightens high Pylint complexity thresholds left over from the old package-root monolith. ## 📋 Changes Summary - Removed `KleinanzeigenBot` from `src/kleinanzeigen_bot/__init__.py`. - Updated all remaining test imports to use `from kleinanzeigen_bot.app import KleinanzeigenBot`. - Enabled `C90`/mccabe complexity linting with an explicit `max-complexity`. - Lowered the broad Pylint limits for branches, locals, returns, statements, and public methods. - Kept the generated/static pydantic error-code mapping explicitly exempted from complexity checks. - No runtime behavior, CLI, config, translations, or ad YAML changes. - No new dependencies. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [x] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Reorganized internal module import structure for consistency across the codebase. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
d0d8e5461b |
refactor: move shipping form tests (#1147)
## ℹ️ Description - Link to the related issue(s): Issue # - Move the shipping option mapping test to the publishing form test module, where the browser-level shipping form behavior is owned. ## 📋 Changes Summary - Moved `test_shipping_options_mapping` from `tests/unit/test_init.py` to `tests/unit/test_publishing_form.py`. - Kept the existing assertions and patch targets intact. - Renamed the remaining `test_init.py` class to describe its cross-drive path fallback coverage. - No runtime behavior, CLI, config, translation, or ad YAML changes. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Reorganized test coverage for publishing and shipping functionality * Added tests for Windows cross-drive path fallback behavior * Added tests for shipping options mapping verification <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
29aed68706 |
refactor: move publishing workflow tests (#1142)
## ℹ️ Description - Link to the related issue(s): Follow-up to #1141 - Move a publishing/update orchestration test slice into the publishing workflow test module. - Share duplicated test fixtures/helpers that are now used by the relocated publishing workflow tests and existing related tests. - This remains behavior-neutral test organization only. ## 📋 Changes Summary - Added `tests/unit/test_publishing_workflow.py` for publishing workflow orchestration tests. - Moved `TestKleinanzeigenBotUpdateAdsResilience` out of `tests/unit/test_init.py`. - Updated the relocated tests to import `KleinanzeigenBot` directly from `kleinanzeigen_bot.app`. - Moved the duplicated `base_ad_config` fixture into `tests/conftest.py`. - Extracted shared `build_update_ad` and `build_published_ads` test helpers into `tests/conftest.py`. - Removed duplicate fixture/helper definitions from affected unit test files. - No runtime behavior, CLI output, config parsing, translations, or ad YAML handling changes. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) - [x] Maintenance/refactor (tests only, no runtime behavior change) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added comprehensive tests for ad publishing resilience and orchestration, covering retry mechanisms, error handling, timeout scenarios, and failure propagation across different ad states * Reorganized and consolidated test utilities, shared fixtures, and builder helpers across test modules <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
35bd393dc4 |
refactor: extract login/auth flow into login_flow.py (#1139)
## ℹ️ Description Extract all login, Auth0 form-fill, captcha, SMS/email verification, GDPR, login-state detection, and diagnostics-capture logic from `__init__.py` into a new `login_flow.py` module. ## 📋 Changes Summary - Create `login_flow.py` (~634 lines) with module-level async functions accepting explicit `web: WebScrapingMixin` + keyword arguments - Thin delegators in `__init__.py` bind `KleinanzeigenBot` instance attributes to module calls - Remove 12 dead delegator methods; tests call module functions directly - Move `LoginDetectionResult`/`LoginDetectionReason` types to `login_flow` - Move `TestKleinanzeigenBotAuthentication` to `tests/unit/test_login_flow.py`, update patch targets - Move login translations to `login_flow.py` section in `translations.de.yaml` - Fix diagnostics guard reset per login attempt - Remove `is_logged_in_web()`; pass username explicitly - Make cross-module functions public: `login_flow` internal helpers and `WebScrapingMixin` helpers (`dismiss_consent_banner`, `effective_timeout`, `extract_visible_text`) ### ⚙️ Type of Change - [x] ✨ New feature (adds new functionality without breaking existing usage) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Refactor** * Reworked the authentication/login process to use a dedicated login flow, improving handling of multi-step sign-in and related verification prompts. * Standardized login-status detection and diagnostics behavior when login state can’t be determined. * Updated text-extraction and timeout behavior for DOM-based fallbacks, and aligned consent-banner dismissal to the public API. * **Tests** * Added extensive unit tests for the login flow and login-state detection. * Updated existing tests to reflect the refactored helpers and consent-banner method naming. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
154c37b26e |
refactor: extract special-attributes/condition form section (#1135)
## ℹ️ Description Extracts special-attribute and condition form logic from `__init__.py` into `publishing_form.py` to continue module decomposition. ## 📋 Changes Summary - **`publishing_form.py`**: Added `set_special_attributes`, `_set_condition`, and helpers (`_pick_special_attribute_candidate`, `_special_attribute_candidate_priority`, `_describe_special_attribute_candidate`) adapted as module-level functions taking `web: WebScrapingMixin` - **`__init__.py`**: Removed the moved functions, cleaned up stale imports (`re`, `_ad_form_helpers`, `_select_button_combobox`, `ensure`, `Element`), updated `_fill_ad_form` to delegate via `_publishing_form.set_special_attributes()` - **`translations.de.yaml`**: Moved `_set_condition` and `set_special_attributes` sections from `__init__.py:` → `publishing_form.py:` block - **`test_init.py`**: Moved special-attribute and condition tests to `test_publishing_form.py`, updated orchestration patch targets - **`test_publishing_form.py`**: Added `TestSpecialAttributes`, `TestConditionSelector`, and `TestConditionFallbackToGenericHandler` classes with adapted imports and patches ### ⚙️ Type of Change - [x] Refactor — no behavior changes, internal module reorganization only ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. |
||
|
|
875b8b063a |
refactor: extract publishing shipping form section (#1134)
## ℹ️ Description - Extracts the publishing shipping form workflow from `KleinanzeigenBot` into `publishing_form.py`. - Keeps runtime behavior, selectors, waits, messages, and browser interactions unchanged while moving translation ownership. ## 📋 Changes Summary - Move WANTED shipping handling, shipping radio/dialog handling, shipping option toggling, and the private React-fiber button-combobox helper into `publishing_form.py`. - Update `__init__.py` to delegate shipping form work and keep only orchestration/seam responsibilities. - Move direct shipping behavior tests to `tests/unit/test_publishing_form.py`; keep a shipping orchestration seam test in `tests/unit/test_init.py`. - Move German translation entries for shipping messages to the `publishing_form.py` translation section. ### ⚙️ Type of Change - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary of changes * **Refactor** * Improved publishing ad shipping form handling by routing wanted vs non-wanted ads to the correct UI flow. * Enhanced Versand (shipping) combobox selection for wanted ads to ensure the right option is chosen. * Strengthened the shipping dialog flow for pickup vs shipping-with-options, including more reliable shipping price confirmation and retry behavior. * **Tests** * Expanded unit tests covering shipping dialog interactions, carrier/option selection, wanted-shipping combobox behavior, and timeout/error scenarios. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
e9ed698dce |
refactor: extract publishing pricing form section (#1133)
## ℹ️ Description - Link to the related issue(s): Issue # - Extracts the publishing pricing/direct-buy/description form section from the main bot class as the next monolith-breakdown step. ## 📋 Changes Summary - Added publishing_form.set_pricing_fields() for price type/amount, sell-directly/direct-buy radios, and description filling. - Replaced the inline _fill_ad_form() pricing block with the new publishing form section call. - Moved direct unit coverage for pricing/direct-buy/description behavior into test_publishing_form.py and kept orchestration seam tests in test_init.py. - Moved existing German translation ownership entries to the new function path without wording changes. - No dependencies, configuration changes, CLI changes, schema changes, or generated artifacts. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project standards. - [x] I have tested my changes and ensured that all tests pass (pdm run test). - [x] I have formatted the code (pdm run format). - [x] I have verified that linting passes (pdm run lint). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **Refactor** * Centralized pricing-related ad form filling (price type, price amount, ad description with affixes, and direct-buy/buy-now controls) into a shared publishing helper for more consistent behavior. * **Bug Fixes** * Improved handling of pricing/buy-now selection failures by surfacing clearer, localized timeout errors. * **Tests** * Added dedicated coverage for pricing field interactions, including dropdown skipping when not applicable, correct amount input behavior, and description generation usage. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
137a7691a7 |
refactor: extract publishing image form section (#1132)
## ℹ️ Description - Link to the related issue(s): N/A - Extracts the publishing image cleanup and upload section from the bot monolith into `publishing_form.py` as Step 16 of the monolith breakdown plan. ## 📋 Changes Summary - Move image cleanup/upload behavior into `fill_image_section()` and `upload_images()`. - Replace the monolith image block with a publishing form seam call. - Move direct image behavior tests from `test_init.py` to `test_publishing_form.py`. - Update German translation ownership paths without changing translated text. - No dependency, configuration, CLI, schema, or generated artifact changes. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) - [x] ♻️ Refactor (no intended behavior change) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project standards. - [x] I have tested my changes and ensured that all tests pass (`pdm run test`). - [x] I have formatted the code (`pdm run format`). - [x] I have verified that linting passes (`pdm run lint`). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Image upload handling has been reorganized and consolidated in the publishing module for improved code organization. The image processing workflow now includes enhanced timeout management and marker-based completion detection to ensure all images are reliably processed during ad publication. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |
||
|
|
9d146c2b96 |
refactor: extract publishing contact form section (#1131)
## ℹ️ Description - Link to the related issue(s): Issue # - Refactors the publishing form code by moving the contact/location form section out of the package initializer into the publishing form module. ## 📋 Changes Summary - Move contact field handling, contact location handling, and city combobox helpers into publishing_form.py. - Keep the publishing form orchestration delegating through an explicit web/contact boundary. - Update unit tests to patch and call the new publishing form functions. - Move German translation ownership paths for the relocated messages without changing translated text. - No dependencies, configuration changes, or additional requirements introduced. ### ⚙️ Type of Change Select the type(s) of change(s) included in this pull request: - [ ] 🐞 Bug fix (non-breaking change which fixes an issue) - [ ] ✨ New feature (adds new functionality without breaking existing usage) - [ ] 💥 Breaking change (changes that might break existing user setups, scripts, or configurations) ## ✅ Checklist Before requesting a review, confirm the following: - [x] I have reviewed my changes to ensure they meet the project's standards. - [x] I have tested my changes and ensured that all tests pass (pdm run test). - [x] I have formatted the code (pdm run format). - [x] I have verified that linting passes (pdm run lint). - [x] I have updated documentation where necessary. By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Updated ad publishing to populate contact and location fields via dedicated public publishing-form helpers, with revised import wiring for ad model types. * Removed older internal city/contact handling logic and replaced it with clearer helper-driven flow. * **Bug Fixes** * Improved city/location hardening: safer city extraction, combobox-style selection with ambiguity checks, timeout-based fallbacks, and correct handling for read-only city inputs. * More resilient contact field population (zipcode/location, street, name, phone), with graceful handling when optional elements are missing. * **Tests** * Added/updated unit tests to cover city/contact hardening and category probe/picker selection behaviors, asserting helper calls rather than private methods. <!-- end of auto-generated comment: release notes by coderabbit.ai --> |