From b47570f83396f8f2a15b17a8ce38ae199a4cd961 Mon Sep 17 00:00:00 2001 From: James Rosewell Date: Sat, 14 Nov 2026 23:14:33 +0000 Subject: [PATCH 1/3] Test that UserAgents is an empty list when Update Matched User Agent is off --- .../tests/test_update_matched_useragent.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/device-detection/fiftyone_devicedetection_onpremise/tests/test_update_matched_useragent.py b/device-detection/fiftyone_devicedetection_onpremise/tests/test_update_matched_useragent.py index c46e193c..15cca36e 100644 --- a/device-detection/fiftyone_devicedetection_onpremise/tests/test_update_matched_useragent.py +++ b/device-detection/fiftyone_devicedetection_onpremise/tests/test_update_matched_useragent.py @@ -84,9 +84,10 @@ def test_turned_on_populates_user_agents(self): self._user_agents(update_matched_useragent=True)) def test_turned_off_leaves_user_agents_empty(self): - user_agents = self._user_agents(update_matched_useragent=False) - self.assertGreaterEqual(len(user_agents), 1) - self.assertEqual([""] * len(user_agents), user_agents) + # UserAgents is populated only when the option is on, and its + # default is an empty list. + self.assertEqual( + [], self._user_agents(update_matched_useragent=False)) @unittest.skipUnless( From 19be7c895a069be1792c24d5feb6a64802709dee Mon Sep 17 00:00:00 2001 From: James Rosewell Date: Sat, 14 Nov 2026 23:14:35 +0000 Subject: [PATCH 2/3] Give UserAgents as an empty list when the engine does not record the matched User-Agents --- .../devicedetection_onpremise.py | 5 +++++ .../src/fiftyone_devicedetection_onpremise/swig_data.py | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/device-detection/fiftyone_devicedetection_onpremise/src/fiftyone_devicedetection_onpremise/devicedetection_onpremise.py b/device-detection/fiftyone_devicedetection_onpremise/src/fiftyone_devicedetection_onpremise/devicedetection_onpremise.py index 3a078053..28e0ddaa 100644 --- a/device-detection/fiftyone_devicedetection_onpremise/src/fiftyone_devicedetection_onpremise/devicedetection_onpremise.py +++ b/device-detection/fiftyone_devicedetection_onpremise/src/fiftyone_devicedetection_onpremise/devicedetection_onpremise.py @@ -242,6 +242,11 @@ def __init__( if update_matched_useragent is not None: config.setUpdateMatchedUserAgent(update_matched_useragent) + # Whether the matched User-Agents are recorded, which the native + # default turns on. UserAgents is empty when they are not. + self.update_matched_useragent = ( + update_matched_useragent is None or bool(update_matched_useragent)) + if allow_unmatched == True or allow_unmatched == False: config.setAllowUnmatched(allow_unmatched) diff --git a/device-detection/fiftyone_devicedetection_onpremise/src/fiftyone_devicedetection_onpremise/swig_data.py b/device-detection/fiftyone_devicedetection_onpremise/src/fiftyone_devicedetection_onpremise/swig_data.py index e7e6252d..270f7aa4 100644 --- a/device-detection/fiftyone_devicedetection_onpremise/src/fiftyone_devicedetection_onpremise/swig_data.py +++ b/device-detection/fiftyone_devicedetection_onpremise/src/fiftyone_devicedetection_onpremise/swig_data.py @@ -120,6 +120,10 @@ def get_internal(self, key): return AspectPropertyValue(value = self.swig_results.getDeviceId()) if key == 'useragents': + # Populated only when the engine records the matched + # User-Agents, as its default is an empty list. + if not getattr(self.flow_element, "update_matched_useragent", True): + return AspectPropertyValue(value = []) # Each component's result has a matched User-Agent, and several # can match the same one, which is listed once. useragents = [] From 315e30509fc19d7434aa8ca02b4995076d2f66b5 Mon Sep 17 00:00:00 2001 From: James Rosewell Date: Sat, 14 Nov 2026 23:14:51 +0000 Subject: [PATCH 3/3] Stand in for sending usage data while the Device Detection web example test runs and closes --- .../tests/test_onpremisegettingstartedweb.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/device-detection/fiftyone_devicedetection_examples/tests/test_onpremisegettingstartedweb.py b/device-detection/fiftyone_devicedetection_examples/tests/test_onpremisegettingstartedweb.py index 9787fe3c..2ffd2896 100644 --- a/device-detection/fiftyone_devicedetection_examples/tests/test_onpremisegettingstartedweb.py +++ b/device-detection/fiftyone_devicedetection_examples/tests/test_onpremisegettingstartedweb.py @@ -39,11 +39,23 @@ class OnPremiseGettingStartedWebTests(flask_unittest.ClientTestCase): config = GettingStartedWeb.build_config() app = GettingStartedWeb().build(config, logger).app + # The example's config.json shares usage, so sending is stood in for + # while the tests run and while the pipeline closes, and no usage data + # leaves the machine the tests run on. + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.sending = mock.patch("requests.post") + cls.sending.start() + # The example's pipeline lives as long as its app, so it is closed once # the tests are finished with the app. @classmethod def tearDownClass(cls): - GettingStartedWeb.pipeline.close() + try: + GettingStartedWeb.pipeline.close() + finally: + cls.sending.stop() super().tearDownClass() def test_onpremise_getting_started_web(self, client):