qml: defer ReactiveListModel/ReactiveObject initial fetch to componentComplete()
setBaseUrl() and setSource() used to fire refresh() inline as soon as both `baseUrl` and `source` were populated — but setToken() never triggered a refresh. QML evaluates literal property assignments before bindings to other objects' properties, so a model declared with literal `source` plus bindings to `BackendConnection.url` / `BackendConnection.token` (the exact shape of make:bridge:window's output) could fire its GET *before* the `token` binding had landed. The unauthenticated request hit Symfony's SessionAuthenticator, came back 401, and the model parked at `ready === false` with an empty list. Mercure subscribed anonymously (the model explicitly clears the SSE client's bearer), so subsequent server-side mutations propagated fine — masking the initial-fetch failure as "list is empty until something changes". Hit by the second window in examples/todo. Both classes now implement QQmlParserStatus and trigger the initial refresh from componentComplete(), where every binding (literal *and* singleton-derived) is guaranteed to have landed. After completion, individual setter changes still trigger refresh inline — so token rotation / URL reassignment after first load behave unchanged. Regression test under framework/qml/tests/tst_reactive_list_model.qml using the v0.2.0 qmltestrunner harness. Adds a TestHttpServer helper that mimics SessionAuthenticator's 401-on-no-bearer behaviour so the regression is observable; verified the test fails against the unfixed production code (`Actual: ""` vs `Expected: "Bearer testtoken"` on the captured Authorization header). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,13 +8,36 @@
|
||||
#
|
||||
# Or from the skeleton / example Makefiles via `make qmltest`.
|
||||
|
||||
find_package(Qt6 6.5 REQUIRED COMPONENTS QuickTest)
|
||||
find_package(Qt6 6.5 REQUIRED COMPONENTS QuickTest Network)
|
||||
|
||||
# A tiny PhpQml.Bridge.Tests QML module that exposes the in-process
|
||||
# stub HTTP server used by tst_reactive_list_model.qml. Static so it
|
||||
# links into the test exe alongside the production bridge module.
|
||||
qt_add_qml_module(php_qml_bridge_tests
|
||||
URI PhpQml.Bridge.Tests
|
||||
VERSION 1.0
|
||||
STATIC
|
||||
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/PhpQml/Bridge/Tests
|
||||
SOURCES
|
||||
TestHttpServer.h
|
||||
TestHttpServer.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(php_qml_bridge_tests PUBLIC
|
||||
Qt6::Core
|
||||
Qt6::Network
|
||||
Qt6::Qml
|
||||
)
|
||||
|
||||
qt_add_executable(qml_unit_tests main.cpp)
|
||||
target_link_libraries(qml_unit_tests PRIVATE
|
||||
Qt6::QuickTest
|
||||
Qt6::Qml
|
||||
Qt6::Quick
|
||||
php_qml_bridge # production module — type implementations
|
||||
php_qml_bridgeplugin # …and its auto-generated QQmlEngineExtensionPlugin
|
||||
php_qml_bridge_tests # in-process HTTP stub
|
||||
php_qml_bridge_testsplugin # …and its plugin
|
||||
)
|
||||
|
||||
# QUICK_TEST_MAIN reads QUICK_TEST_SOURCE_DIR from the macro definition
|
||||
|
||||
Reference in New Issue
Block a user