Skip to content

2.1.0 — campaign scheduling

Choose a tag to compare

@johnjanney johnjanney released this 01 Aug 04:00
· 65 commits to main since this release

Campaign scheduling, a chooser defect found by review, and the integration
coverage that closes out CODEX-REVIEW.md M-03.

Fixed

  • Two variations of one product, each listed individually, are no longer both
    shown as chosen
    (CODEX-REVIEW.md M-01). Such cards share a parent, and the
    selected-state comparison looked only at the parent — so picking one marked
    both, and because a chosen card shows only "Selected" and "Remove", the
    customer was left with no control anywhere on the page for switching to the
    other. Which card owns the selection is now decided once, where the whole list
    is visible, with a variation listed in its own right taking precedence over the
    parent card that could also offer it.

Changed

  • A page of variable rewards costs far fewer product loads
    (CODEX-REVIEW.md M-02). Rendering asked for the same variation through four
    separate paths: judging the parent a card, enumerating its selector, pricing
    each option, and quoting the card. On a page of 24 variable products with 20
    variations each that was 2,016 product loads against 504 distinct products;
    it is now 552. A test holds the ratio so it cannot drift back.

Added

  • The offer can be given a start date and an end date (OPEN-QUESTIONS.md
    Q-005, DECISION.md D-019). Both are optional and both are inclusive whole
    days in the store's timezone: an offer running "1–7 August" is live on both of
    those days and stops on the 8th. Leaving a field empty leaves that side
    unbounded, and an offer with neither behaves exactly as it did before — every
    existing install is unscheduled, with no migration.

    The settings screen refuses a window that ends before it begins, and says so
    when an enabled offer has already ended or has not started yet, since in both
    cases the storefront looks identical to the offer being switched off.

  • Two tests fix how the Buy quantity counts (OPEN-QUESTIONS.md Q-002,
    confirming DECISION.md D-003). Quantities are summed across everything on the
    Buy list, so one each of two listed products satisfies a Buy 2 offer. A store
    wanting "two of the same product" gives the offer a Buy list of one product,
    which needs no new setting — a recipe now in INSTRUCTIONS.md §4 and held by a
    test, since untested advice rots.

  • Shipping behaviour is covered, answering OPEN-QUESTIONS.md Q-004. That
    question had stated from the beginning that a free reward adds weight to the
    parcel but nothing to order value, and nothing had ever checked it — every
    other fixture uses virtual products so that shipping stays out of the way.
    Measured now, in both modes: a free reward leaves the order value untouched and
    cannot carry a customer over a free-shipping threshold, a discounted one adds
    its own reduced price and can, and either joins the parcel.

  • A real order is now placed in CI, and its metadata and stock asserted
    (CODEX-REVIEW.md M-03). The plugin writes reward metadata on
    woocommerce_checkout_create_order_line_item, a hook nothing in CI had ever
    fired — BRIEF.md §8.6 listed order placement, order metadata, and stock
    reduction as verified by hand. A new lane builds a qualifying cart over the
    Store API, checks out through it, and then inspects what landed: the reward
    line and its quantity, the discounted line total, both meta keys, the visible
    label, and stock down by the awarded quantity rather than by one.

  • The classic cart and checkout are covered in a real browser. Every browser
    assertion until now ran against the Cart and Checkout blocks, because that is
    what WooCommerce provisions on a fresh install — but the shortcode path is
    different code on both sides, reaching the page through template hooks rather
    than the render_block filter and choosing over admin-ajax rather than the
    Store API. The reward is chosen by clicking the button, so the JavaScript and
    the reload that classic mode performs are covered too, along with the badge,
    the discounted price, the locked quantity, and the checkout slot being marked
    so it never reloads a part-filled form.

  • Tax on a discounted reward is covered, in both display modes. The plugin
    sets the line's price before totals run, so tax should follow the discounted
    figure rather than the price it was discounted from — the difference a store
    would feel, and never checked until now. A store whose prices exclude tax
    charges 10.00 plus tax on a 20.00 reward at half price; one whose prices
    include tax charges exactly 10.00, tax included. Both are asserted, along with
    the rate being applied to the discounted line rather than the original.

  • Coupon behaviour alongside a reward is now tested rather than reasoned.
    The 1.3.0 notes said eligible coupons stack on the strength of where the
    pricing hook sits, since the unit stubs have no coupon support. Both halves are
    now covered against a real store: an eligible 20% coupon over a 50% reward
    leaves the customer paying 40% of list, and a coupon excluding the reward
    leaves it untouched while still discounting the rest of the cart.

  • tests/README.md describes what is actually run. It had gone stale in the
    opposite direction, still saying there was no database, HTTP, WordPress
    install, JavaScript runner, or real block rendering — all of which the
    integration job has done since 1.2.1. It now covers both suites and is
    explicit about what neither reaches.