From 44d83d699665ffc7b07c9fefefa81b3ae8baa475 Mon Sep 17 00:00:00 2001 From: Christopher Kittel Date: Sat, 23 Mar 2024 01:40:44 +0100 Subject: [PATCH 01/20] Update getChartSVG.js --- server/services/getChartSVG.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/services/getChartSVG.js b/server/services/getChartSVG.js index dea2fe48b..7fff158c5 100644 --- a/server/services/getChartSVG.js +++ b/server/services/getChartSVG.js @@ -10,8 +10,8 @@ function timeout(ms) { const page = await browser.newPage(); await page.setViewport({width: 1920, height: 1080}) await page.goto(process.argv[2], {waitUntil: 'networkidle2'}); - await timeout(3000) + await timeout(1000) await page.screenshot({path: process.argv[3], clip: { x: 0, y: 0, width: 1150, height: 1080 }}); browser.close(); -})(); \ No newline at end of file +})(); From fa92d2a91e596c029e020888286b8aff87efa388 Mon Sep 17 00:00:00 2001 From: chreman Date: Sun, 28 Apr 2024 20:44:33 +0200 Subject: [PATCH 02/20] generalize dateparsing --- server/workers/base/requirements.txt | 1 + server/workers/base/src/base.py | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/server/workers/base/requirements.txt b/server/workers/base/requirements.txt index 614689b2a..9d94e576a 100644 --- a/server/workers/base/requirements.txt +++ b/server/workers/base/requirements.txt @@ -1,6 +1,7 @@ asn1crypto==0.24.0 async-timeout==4.0.2 cryptography==2.1.4 +dateparser==1.1.3 idna==2.6 importlib-metadata==4.8.3 keyring==10.6.0 diff --git a/server/workers/base/src/base.py b/server/workers/base/src/base.py index ca29ac6a2..d08b8f31d 100644 --- a/server/workers/base/src/base.py +++ b/server/workers/base/src/base.py @@ -12,6 +12,7 @@ from parsers import improved_df_parsing from datetime import datetime +import dateparser import sys formatter = logging.Formatter(fmt='%(asctime)s %(levelname)-8s %(message)s', @@ -382,7 +383,8 @@ def sanitize_year(year_str): for fmt in date_formats: try: - date_time_obj = datetime.strptime(year_str, fmt) + #date_time_obj = datetime.strptime(year_str, fmt) + dateparser.parse(year_str) sanitized_year = year_str # here we keep the original string break except ValueError: From c14c0e8311d2776eaac19edf857343e78118f88a Mon Sep 17 00:00:00 2001 From: chreman Date: Sun, 3 Nov 2024 14:01:42 +0100 Subject: [PATCH 03/20] temporary logging statements --- .gitignore | 1 + docker-compose.yml | 2 -- local_dev/proxy/docker-compose.yml | 2 -- .../classes/headstart/library/APIClient.php | 3 +++ .../persistence/PostgresPersistence.php | 7 ++++++- server/services/getLastVersion.php | 1 + server/services/search.php | 7 ++++++- server/workers/persistence/src/app.py | 2 ++ server/workers/persistence/src/persistence.py | 19 +++++++++++++++++++ 9 files changed, 38 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index d70ade073..abc908e04 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ server/workers/tests/*.csv server/workers/tests/*.txt server/workers/tests/testutils/ local_dev/renv/* +local_dev/dev.env # php files /server/classes/headstart/vendor diff --git a/docker-compose.yml b/docker-compose.yml index c7c721434..0a40186f7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.7' - services: db: diff --git a/local_dev/proxy/docker-compose.yml b/local_dev/proxy/docker-compose.yml index aeb843da2..95bbf6f28 100644 --- a/local_dev/proxy/docker-compose.yml +++ b/local_dev/proxy/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.7' - services: proxy: diff --git a/server/classes/headstart/library/APIClient.php b/server/classes/headstart/library/APIClient.php index bac1a0482..e5d9d0612 100644 --- a/server/classes/headstart/library/APIClient.php +++ b/server/classes/headstart/library/APIClient.php @@ -32,6 +32,7 @@ public function call_api($endpoint, $payload) { return $res; } catch (Exception $e) { + error_log("Error in APIClient: " . $e); $res = array("status"=>"error", "httpcode"=>500, "reason"=>array("unexpected data processing error")); @@ -67,6 +68,7 @@ public function handle_api_errors($res) { // $res = array("status"=>"error", reason=>array()); // } // } + error_log(("Trying to handle API errors: " . print_r($res, true))); $res["status"] = "error"; if ($res["httpcode"] == 503) { $res["reason"] = array(); @@ -77,6 +79,7 @@ public function handle_api_errors($res) { if (count($res["reason"])==0) { array_push($res["reason"], "unexpected data processing error"); } + error_log(("Trying to handle API errors: " . print_r($res, true))); return $res; } diff --git a/server/classes/headstart/persistence/PostgresPersistence.php b/server/classes/headstart/persistence/PostgresPersistence.php index 0f247be2d..3dacc5b23 100644 --- a/server/classes/headstart/persistence/PostgresPersistence.php +++ b/server/classes/headstart/persistence/PostgresPersistence.php @@ -64,14 +64,19 @@ public function getLastVersion($vis_id, $details, $context): array|bool "details" => $details, "context" => $context)); $res = $this->api_client->call_persistence("getLastVersion", $payload); + error_log(message: "raw result: " . print_r($res, true)); + error_log(message: "result http code: " . $res["httpcode"]); if ($res["httpcode"] != 200) { - $data = $res; + $data = $res; } else { $data = json_decode($res["result"], true); } if ($data != "null") { $data = array($data); } + //hypothesis: does not return a response that search.php can recognize as failed search/request + error_log("raw data: " . print_r($data, true)); + error_log("data: " . json_encode($data)); return $data; } diff --git a/server/services/getLastVersion.php b/server/services/getLastVersion.php index c18be5762..314e0c76e 100644 --- a/server/services/getLastVersion.php +++ b/server/services/getLastVersion.php @@ -24,6 +24,7 @@ if ($last_version != null && $last_version != "null" && $last_version != false) { + //this logic no longer works with the new postgres database echo json_encode(array("status" => "success", "last_version" => $last_version)); } else { echo json_encode(array("status" => "error")); diff --git a/server/services/search.php b/server/services/search.php index 23808a5d3..05bbe3f5b 100644 --- a/server/services/search.php +++ b/server/services/search.php @@ -107,12 +107,17 @@ function search($service, $dirty_query $repo_name = $res["repo_name"]; $post_params["repo_name"] = $repo_name; $param_types[] = "repo_name"; - // this is not duplicate code, the $params_json needs to be updated with the addition metadata + // this is not duplicate code, the $params_json needs to be updated with the additional metadata $params_json = packParamsJSON($param_types, $post_params); } if($retrieve_cached_map) { $last_version = $persistence->getLastVersion($unique_id, false, false); + //todo: log output of $last_version + // log to docker logs + error_log(message: "type of last_version: " . gettype($last_version)); + error_log(message: "raw array of last_version: " . print_r($last_version, true)); + error_log("last_version: " . json_encode($last_version)); if ($last_version != null && $last_version != "null" && $last_version != false) { echo json_encode(array("query" => $query, "id" => $unique_id, "status" => "success")); return; diff --git a/server/workers/persistence/src/app.py b/server/workers/persistence/src/app.py index 48aafba9a..ddd5c4fb5 100644 --- a/server/workers/persistence/src/app.py +++ b/server/workers/persistence/src/app.py @@ -55,6 +55,8 @@ def api_patches(app): app = Flask('v1', instance_relative_config=True) +# add logging to docker logs +app.logger.setLevel(logging.DEBUG) handler = logging.StreamHandler(sys.stdout) handler.setLevel(app.logger.level) app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_port=1, x_for=1, x_host=1, x_prefix=1) diff --git a/server/workers/persistence/src/persistence.py b/server/workers/persistence/src/persistence.py index 8d22fb0f1..9a495a79a 100644 --- a/server/workers/persistence/src/persistence.py +++ b/server/workers/persistence/src/persistence.py @@ -8,6 +8,7 @@ from models import Revisions, Visualizations from database import Session +from sqlalchemy.exc import OperationalError persistence_ns = Namespace("persistence", description="OKMAps persistence operations") @@ -252,7 +253,17 @@ def post(self, database): return make_response(jsonify(result), 200, headers) + # catch database connection error + except OperationalError as e: + # also log the stack trace + persistence_ns.logger.error("getLastVersion: %s" % str(e), exc_info=True) + result = {'success': False, 'reason': ["database connection error"]} + headers = {'ContentType': 'application/json'} + return make_response(jsonify(result), + 500, + headers) except Exception as e: + persistence_ns.logger.error("getLastVersion: %s" % str(e), exc_info=True) result = {'success': False, 'reason': [str(e)]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), @@ -290,7 +301,15 @@ def post(self, database): return make_response(jsonify(result), 200, headers) + except OperationalError as e: + persistence_ns.logger.error("getContext: %s" % str(e), exc_info=True) + result = {'success': False, 'reason': ["database connection error"]} + headers = {'ContentType': 'application/json'} + return make_response(jsonify(result), + 500, + headers) except Exception as e: + persistence_ns.logger.error("getContext: %s" % str(e), exc_info=True) result = {'success': False, 'reason': [str(e)]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), From c688a0b07387ff05d8478a2f5fe26a4bf2e522d8 Mon Sep 17 00:00:00 2001 From: chreman Date: Wed, 11 Dec 2024 20:56:10 +0100 Subject: [PATCH 04/20] logging and error handling wip --- server/services/search.php | 16 ++++++++++++---- server/workers/api/Dockerfile | 1 - server/workers/persistence/src/persistence.py | 15 +++++++++------ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/server/services/search.php b/server/services/search.php index 05bbe3f5b..8d41ac4d8 100644 --- a/server/services/search.php +++ b/server/services/search.php @@ -112,12 +112,20 @@ function search($service, $dirty_query } if($retrieve_cached_map) { - $last_version = $persistence->getLastVersion($unique_id, false, false); + $last_version = $persistence->getLastVersion($unique_id, false, false)[0]; //todo: log output of $last_version // log to docker logs - error_log(message: "type of last_version: " . gettype($last_version)); - error_log(message: "raw array of last_version: " . print_r($last_version, true)); - error_log("last_version: " . json_encode($last_version)); + + error_log(message: "search.php: type of last_version: " . gettype($last_version)); + error_log(message: "search.php: keys of last_version: " . print_r(array_keys($last_version), true)); + error_log(message: "search.php: raw array of last_version: " . print_r($last_version, true)); + error_log(message: "search.php: raw array of last_version: " . print_r($last_version["result"], true)); + error_log("search.php: last_version: " . json_decode($last_version["result"], true)); + // check if success-status of last_version call is false + if ($last_version["httpcode"] != 200) { + return json_encode($last_version["result"]); + } + if ($last_version != null && $last_version != "null" && $last_version != false) { echo json_encode(array("query" => $query, "id" => $unique_id, "status" => "success")); return; diff --git a/server/workers/api/Dockerfile b/server/workers/api/Dockerfile index 01418d71f..d2ab2f09f 100644 --- a/server/workers/api/Dockerfile +++ b/server/workers/api/Dockerfile @@ -8,7 +8,6 @@ RUN apt-get install -y gcc git libpq-dev WORKDIR /api COPY workers/api/requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -RUN pip install git+https://github.com/python-restx/flask-restx COPY workers/api/src/ ./ diff --git a/server/workers/persistence/src/persistence.py b/server/workers/persistence/src/persistence.py index 9a495a79a..14cef7bd9 100644 --- a/server/workers/persistence/src/persistence.py +++ b/server/workers/persistence/src/persistence.py @@ -156,6 +156,9 @@ def get_context(database, vis_id, revision_context=False): except TypeError: persistence_ns.logger.debug("get_context: Vis ID not found: %s in database %s" % (vis_id, database)) res = [False] + except OperationalError as e: + persistence_ns.logger.error("get_context: %s" % str(e), exc_info=True) + res = {"status": "error", 'reason': ["database connection error"]} session.close() return res @@ -197,13 +200,13 @@ def post(self, database): create_visualization(database, vis_id, vis_title, data, vis_clean_query, vis_query, vis_params) - result = {'success': True} + result = {'status': "success"} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 200, headers) except Exception as e: - result = {'success': False, 'reason': [str(e)]} + result = {'status': "error", 'reason': [str(e)]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 500, @@ -222,11 +225,11 @@ def post(self, database): data = payload.get("data") # persistence_ns.logger.debug(data) write_revision(database, vis_id, data) - result = {'success': True} + result = {'status': "success"} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 200, headers) except Exception as e: - result = {'success': False, 'reason': [str(e)]} + result = {'status': "error", 'reason': [str(e)]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 500, headers) @@ -257,14 +260,14 @@ def post(self, database): except OperationalError as e: # also log the stack trace persistence_ns.logger.error("getLastVersion: %s" % str(e), exc_info=True) - result = {'success': False, 'reason': ["database connection error"]} + result = {'status': "error", 'reason': ["database connection error"]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 500, headers) except Exception as e: persistence_ns.logger.error("getLastVersion: %s" % str(e), exc_info=True) - result = {'success': False, 'reason': [str(e)]} + result = {'status': "error", 'reason': [str(e)]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 500, From e57f9f818d9f38f82504c249211e6003768c9a99 Mon Sep 17 00:00:00 2001 From: chreman Date: Sun, 15 Dec 2024 20:35:25 +0100 Subject: [PATCH 05/20] database error handling bugfixes and logging --- .../headstart/persistence/PostgresPersistence.php | 12 ++++++++---- server/services/search.php | 12 +++++------- server/workers/persistence/src/persistence.py | 10 +++++----- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/server/classes/headstart/persistence/PostgresPersistence.php b/server/classes/headstart/persistence/PostgresPersistence.php index 3dacc5b23..dff00ac42 100644 --- a/server/classes/headstart/persistence/PostgresPersistence.php +++ b/server/classes/headstart/persistence/PostgresPersistence.php @@ -64,19 +64,23 @@ public function getLastVersion($vis_id, $details, $context): array|bool "details" => $details, "context" => $context)); $res = $this->api_client->call_persistence("getLastVersion", $payload); - error_log(message: "raw result: " . print_r($res, true)); - error_log(message: "result http code: " . $res["httpcode"]); + error_log(message: "PostgresPersistence.php: raw result: " . print_r($res, true)); + // this sometimes looks like array("result" => "null", "httpcode" => 200) + error_log(message: "PostgresPersistence.php: result http code: " . $res["httpcode"]); if ($res["httpcode"] != 200) { + // we could throw here and then handle the error in the calling function, e.g. getLastVersion.php $data = $res; } else { + // in case of an error with misleading http code, the result is unpacked and returned $data = json_decode($res["result"], true); } if ($data != "null") { + // this is a workaround for the case that the result is not an array $data = array($data); } //hypothesis: does not return a response that search.php can recognize as failed search/request - error_log("raw data: " . print_r($data, true)); - error_log("data: " . json_encode($data)); + error_log("PostgresPersistence.php: raw data: " . print_r($data, true)); + error_log("PostgresPersistence.php: data: " . json_encode($data)); return $data; } diff --git a/server/services/search.php b/server/services/search.php index 8d41ac4d8..da622f395 100644 --- a/server/services/search.php +++ b/server/services/search.php @@ -115,18 +115,16 @@ function search($service, $dirty_query $last_version = $persistence->getLastVersion($unique_id, false, false)[0]; //todo: log output of $last_version // log to docker logs - - error_log(message: "search.php: type of last_version: " . gettype($last_version)); - error_log(message: "search.php: keys of last_version: " . print_r(array_keys($last_version), true)); - error_log(message: "search.php: raw array of last_version: " . print_r($last_version, true)); - error_log(message: "search.php: raw array of last_version: " . print_r($last_version["result"], true)); - error_log("search.php: last_version: " . json_decode($last_version["result"], true)); + // check if success-status of last_version call is false if ($last_version["httpcode"] != 200) { - return json_encode($last_version["result"]); + error_log("search.php: last_version call failed with http code " . $last_version["httpcode"]); + error_log("search.php: last_version call failed with result " . $last_version["result"]); + return $last_version["result"]; } if ($last_version != null && $last_version != "null" && $last_version != false) { + // for example, non-existant vis_id is handled here, which looks like [False] echo json_encode(array("query" => $query, "id" => $unique_id, "status" => "success")); return; } diff --git a/server/workers/persistence/src/persistence.py b/server/workers/persistence/src/persistence.py index 14cef7bd9..0708639e7 100644 --- a/server/workers/persistence/src/persistence.py +++ b/server/workers/persistence/src/persistence.py @@ -128,7 +128,7 @@ def get_revision(database, vis_id, rev_id, details=False, context=False): res = rev.rev_data except TypeError: persistence_ns.logger.debug("get_revision: Vis ID not found: %s in database %s" % (vis_id, database)) - res = "null" + res = "null" session.close() return res @@ -156,9 +156,7 @@ def get_context(database, vis_id, revision_context=False): except TypeError: persistence_ns.logger.debug("get_context: Vis ID not found: %s in database %s" % (vis_id, database)) res = [False] - except OperationalError as e: - persistence_ns.logger.error("get_context: %s" % str(e), exc_info=True) - res = {"status": "error", 'reason': ["database connection error"]} + # session.close() return res @@ -263,7 +261,7 @@ def post(self, database): result = {'status': "error", 'reason': ["database connection error"]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), - 500, + 503, headers) except Exception as e: persistence_ns.logger.error("getLastVersion: %s" % str(e), exc_info=True) @@ -299,12 +297,14 @@ def post(self, database): vis_id = payload.get('vis_id') revision_context = payload.get('revision_context', False) result = get_context(database, vis_id, revision_context) + # when error, then result is a list [False] persistence_ns.logger.debug(result) headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 200, headers) except OperationalError as e: + # this is not yet working, in the sense the search flow does not react to it persistence_ns.logger.error("getContext: %s" % str(e), exc_info=True) result = {'success': False, 'reason': ["database connection error"]} headers = {'ContentType': 'application/json'} From 2d270f84bc28e57d6bedc7aa9f5d55348531cc52 Mon Sep 17 00:00:00 2001 From: chreman Date: Mon, 16 Dec 2024 13:51:43 +0100 Subject: [PATCH 06/20] clean up problematic changes --- .../persistence/PostgresPersistence.php | 8 ++++---- server/services/search.php | 14 +++++++------- server/workers/persistence/src/persistence.py | 18 ++++++++++++------ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/server/classes/headstart/persistence/PostgresPersistence.php b/server/classes/headstart/persistence/PostgresPersistence.php index dff00ac42..7bd67438c 100644 --- a/server/classes/headstart/persistence/PostgresPersistence.php +++ b/server/classes/headstart/persistence/PostgresPersistence.php @@ -64,9 +64,9 @@ public function getLastVersion($vis_id, $details, $context): array|bool "details" => $details, "context" => $context)); $res = $this->api_client->call_persistence("getLastVersion", $payload); - error_log(message: "PostgresPersistence.php: raw result: " . print_r($res, true)); + // error_log(message: "PostgresPersistence.php: raw result: " . print_r($res, true)); // this sometimes looks like array("result" => "null", "httpcode" => 200) - error_log(message: "PostgresPersistence.php: result http code: " . $res["httpcode"]); + // error_log(message: "PostgresPersistence.php: result http code: " . $res["httpcode"]); if ($res["httpcode"] != 200) { // we could throw here and then handle the error in the calling function, e.g. getLastVersion.php $data = $res; @@ -79,8 +79,8 @@ public function getLastVersion($vis_id, $details, $context): array|bool $data = array($data); } //hypothesis: does not return a response that search.php can recognize as failed search/request - error_log("PostgresPersistence.php: raw data: " . print_r($data, true)); - error_log("PostgresPersistence.php: data: " . json_encode($data)); + // error_log("PostgresPersistence.php: raw data: " . print_r($data, true)); + // error_log("PostgresPersistence.php: data: " . json_encode($data)); return $data; } diff --git a/server/services/search.php b/server/services/search.php index da622f395..4fc9df002 100644 --- a/server/services/search.php +++ b/server/services/search.php @@ -112,7 +112,13 @@ function search($service, $dirty_query } if($retrieve_cached_map) { - $last_version = $persistence->getLastVersion($unique_id, false, false)[0]; + $last_version = $persistence->getLastVersion($unique_id, false, false); + if ($last_version != null && $last_version != "null" && $last_version != false) { + error_log("search.php: last_version call returned " . print_r($last_version, true)); + // for example, non-existant vis_id is handled here, which looks like [False] + echo json_encode(array("query" => $query, "id" => $unique_id, "status" => "success")); + return; + } //todo: log output of $last_version // log to docker logs @@ -122,12 +128,6 @@ function search($service, $dirty_query error_log("search.php: last_version call failed with result " . $last_version["result"]); return $last_version["result"]; } - - if ($last_version != null && $last_version != "null" && $last_version != false) { - // for example, non-existant vis_id is handled here, which looks like [False] - echo json_encode(array("query" => $query, "id" => $unique_id, "status" => "success")); - return; - } } $payload = json_encode($post_params); diff --git a/server/workers/persistence/src/persistence.py b/server/workers/persistence/src/persistence.py index 0708639e7..7017ddb69 100644 --- a/server/workers/persistence/src/persistence.py +++ b/server/workers/persistence/src/persistence.py @@ -156,7 +156,6 @@ def get_context(database, vis_id, revision_context=False): except TypeError: persistence_ns.logger.debug("get_context: Vis ID not found: %s in database %s" % (vis_id, database)) res = [False] - # session.close() return res @@ -198,13 +197,15 @@ def post(self, database): create_visualization(database, vis_id, vis_title, data, vis_clean_query, vis_query, vis_params) - result = {'status': "success"} + # result = {'status': "success"} + result = {'success': True} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 200, headers) except Exception as e: - result = {'status': "error", 'reason': [str(e)]} + result = {'success': False, 'reason': [str(e)]} + # result = {'status': "error", 'reason': [str(e)]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 500, @@ -223,11 +224,13 @@ def post(self, database): data = payload.get("data") # persistence_ns.logger.debug(data) write_revision(database, vis_id, data) - result = {'status': "success"} + result = {'success': True} + # result = {'status': "success"} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 200, headers) except Exception as e: - result = {'status': "error", 'reason': [str(e)]} + result = {'success': False, 'reason': [str(e)]} + # result = {'status': "error", 'reason': [str(e)]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 500, headers) @@ -265,7 +268,10 @@ def post(self, database): headers) except Exception as e: persistence_ns.logger.error("getLastVersion: %s" % str(e), exc_info=True) - result = {'status': "error", 'reason': [str(e)]} + # it says success because function executeSearchRequest() in search.js expects it + # and does an output.status === "success" check against it + result = {'success': False, 'reason': [str(e)]} + # result = {'status': "error", 'reason': [str(e)]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), 500, From 91eb13b0c44dda68015831a981f5388ee0a91e6c Mon Sep 17 00:00:00 2001 From: Thomas Arrow Date: Mon, 16 Dec 2024 16:19:01 +0000 Subject: [PATCH 07/20] TomChris thoughts from 2024-12-16 working session --- .../classes/headstart/.phpunit.result.cache | 1 + server/classes/headstart/composer.lock | 1266 +++++++---------- .../tests/DispatchingPersistenceTest.php | 5 + .../tests/PostgresPersistenceTest.php | 60 + .../successfulGetContextResponse.json | 7 + ...ssfulGetContextDBHostCannotBeResolved.json | 6 + ...cessfulgetContextResponseVisIdNotInDB.json | 3 + server/services/getContext.php | 21 +- 8 files changed, 609 insertions(+), 760 deletions(-) create mode 100644 server/classes/headstart/.phpunit.result.cache create mode 100644 server/classes/headstart/tests/PostgresPersistenceTest.php create mode 100644 server/classes/headstart/tests/test_data/successfulGetContextResponse.json create mode 100644 server/classes/headstart/tests/test_data/unsuccessfulGetContextDBHostCannotBeResolved.json create mode 100644 server/classes/headstart/tests/test_data/unsuccessfulgetContextResponseVisIdNotInDB.json diff --git a/server/classes/headstart/.phpunit.result.cache b/server/classes/headstart/.phpunit.result.cache new file mode 100644 index 000000000..494fe2476 --- /dev/null +++ b/server/classes/headstart/.phpunit.result.cache @@ -0,0 +1 @@ +{"version":1,"defects":{"headstart\\tests\\DispatchingPersistenceTest::testCreateVisualizationDispatcherToOldPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testGetRevisionDispatchesToNewPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testWriteRevisionDispatchesToNewPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testExistsVisualizationDispatchesToNewPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testGetLastVersionDispatchesToOldPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testGetLastVersionDispatchesToNewPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testGetLatestRevisionsDispatchesToNewPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testCreateID":2,"headstart\\tests\\DispatchingPersistenceTest::testGetRevisionDispatchesToOldPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testWriteRevisionDispatchesToOldPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testExistsVisualizationDispatchesToOldPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testGetLatestRevisionsDispatchesToOldPersistence":2,"headstart\\tests\\DispatchingPersistenceTest::testGetContextDispatchesToOldPersistence":2,"headstart\\tests\\PostgresPersistenceTest::testCreateVisualizationDispatcherToOldPersistence":5,"headstart\\tests\\PostgresPersistenceTest::test":5,"headstart\\tests\\PostgresPersistenceTest::testThatInSuccesfulConditionsReturnsAResponseObjectWeCanHandle":5,"headstart\\tests\\PostgresPersistenceTest::testWhenDBMissingReturnsAResponseObjectWeCanHandle":5},"times":{"headstart\\tests\\DispatchingPersistenceTest::testCreateVisualizationDispatcherToOldPersistence":0,"headstart\\tests\\DispatchingPersistenceTest::testGetRevisionDispatchesToOldPersistence":0,"headstart\\tests\\DispatchingPersistenceTest::testGetRevisionDispatchesToNewPersistence":0.001,"headstart\\tests\\DispatchingPersistenceTest::testWriteRevisionDispatchesToOldPersistence":0,"headstart\\tests\\DispatchingPersistenceTest::testWriteRevisionDispatchesToNewPersistence":0,"headstart\\tests\\DispatchingPersistenceTest::testExistsVisualizationDispatchesToOldPersistence":0,"headstart\\tests\\DispatchingPersistenceTest::testExistsVisualizationDispatchesToNewPersistence":0,"headstart\\tests\\DispatchingPersistenceTest::testGetLastVersionDispatchesToOldPersistence":0.007,"headstart\\tests\\DispatchingPersistenceTest::testGetLastVersionDispatchesToNewPersistence":0,"headstart\\tests\\DispatchingPersistenceTest::testGetLatestRevisionsDispatchesToOldPersistence":0,"headstart\\tests\\DispatchingPersistenceTest::testGetLatestRevisionsDispatchesToNewPersistence":0,"headstart\\tests\\DispatchingPersistenceTest::testGetContextDispatchesToOldPersistence":0,"headstart\\tests\\DispatchingPersistenceTest::testCreateID":0,"headstart\\DbConnectionTest::testCreateVisualizationAndRetrieve":0.01,"headstart\\tests\\PostgresPersistenceTest::testCreateVisualizationDispatcherToOldPersistence":0,"headstart\\tests\\PostgresPersistenceTest::test":0.001,"headstart\\tests\\PostgresPersistenceTest::testThatInSuccesfulConditionsReturnsAResponseObjectWeCanHandle":0.003,"headstart\\tests\\PostgresPersistenceTest::testWhenDBMissingReturnsAResponseObjectWeCanHandle":0,"headstart\\tests\\PostgresPersistenceTest::testWhenVisIDNotInDBReturnsAResponseObjectWeCanHandle":0}} \ No newline at end of file diff --git a/server/classes/headstart/composer.lock b/server/classes/headstart/composer.lock index b4e6480c2..407da8237 100644 --- a/server/classes/headstart/composer.lock +++ b/server/classes/headstart/composer.lock @@ -4,209 +4,153 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e771e925f84aadb6dcb911900c72ad94", + "content-hash": "a4b5d7f7252fe9b0f06c5b8ce897fb22", "packages": [], "packages-dev": [ { - "name": "doctrine/deprecations", - "version": "v1.1.1", + "name": "myclabs/deep-copy", + "version": "1.12.1", "source": { "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", - "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, - "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", - "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.1.1" - }, - "time": "2023-06-03T09:27:29+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^11", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.30 || ^5.4" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + "DeepCopy\\": "src/DeepCopy/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "description": "Create deep copies (clones) of your objects", "keywords": [ - "constructor", - "instantiate" + "clone", + "copy", + "duplicate", + "object", + "object graph" ], "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", "type": "tidelift" } ], - "time": "2022-12-30T00:15:36+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { - "name": "myclabs/deep-copy", - "version": "1.11.1", + "name": "nikic/php-parser", + "version": "v5.3.1", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], "psr-4": { - "DeepCopy\\": "src/DeepCopy/" + "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], - "description": "Create deep copies (clones) of your objects", + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "parser", + "php" ], "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-10-08T18:51:32+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -238,26 +182,32 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/master" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2018-07-08T19:23:20+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", - "version": "2.0.1", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -288,331 +238,51 @@ ], "description": "Library for handling version information and constraints", "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/master" - }, - "time": "2018-07-08T19:19:57+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.7.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "b2fe4d22a5426f38e014855322200b97b5362c0d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b2fe4d22a5426f38e014855322200b97b5362c0d", - "reference": "b2fe4d22a5426f38e014855322200b97b5362c0d", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.13" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.2" - }, - "time": "2023-05-30T18:13:47+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.17.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/15873c65b207b07765dbc3c95d20fdf4a320cbe2", - "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2 || ^2.0", - "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.17.0" - }, - "time": "2023-02-02T15:41:36+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.22.0", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "ec58baf7b3c7f1c81b3b00617c953249fb8cf30c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/ec58baf7b3c7f1c81b3b00617c953249fb8cf30c", - "reference": "ec58baf7b3c7f1c81b3b00617c953249fb8cf30c", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/annotations": "^2.0", - "nikic/php-parser": "^4.15", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.22.0" + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "time": "2023-06-01T12:35:21+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "8.0.2", + "version": "10.1.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ca6647ffddd2add025ab3f21644a441d7c146cdc" + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca6647ffddd2add025ab3f21644a441d7c146cdc", - "reference": "ca6647ffddd2add025ab3f21644a441d7c146cdc", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-xmlwriter": "*", - "php": "^7.3", - "phpunit/php-file-iterator": "^3.0", - "phpunit/php-text-template": "^2.0", - "phpunit/php-token-stream": "^4.0", - "sebastian/code-unit-reverse-lookup": "^2.0", - "sebastian/environment": "^5.0", - "sebastian/version": "^3.0", - "theseer/tokenizer": "^1.1.3" + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^10.1" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.0-dev" + "dev-main": "10.1.x-dev" } }, "autoload": { @@ -640,7 +310,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/8.0.2" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, "funding": [ { @@ -648,32 +319,32 @@ "type": "github" } ], - "time": "2020-05-23T08:02:54+00:00" + "time": "2024-08-22T04:31:57+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -700,7 +371,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" }, "funding": [ { @@ -708,28 +380,28 @@ "type": "github" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2023-08-31T06:24:48+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-pcntl": "*" @@ -737,7 +409,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -763,7 +435,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" }, "funding": [ { @@ -771,32 +443,32 @@ "type": "github" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2023-02-03T06:56:09+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.4", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -822,7 +494,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" }, "funding": [ { @@ -830,32 +503,32 @@ "type": "github" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2023-08-31T14:07:24+00:00" }, { "name": "phpunit/php-timer", - "version": "3.1.4", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "dc9368fae6ef2ffa57eba80a7410bcef81df6258" + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/dc9368fae6ef2ffa57eba80a7410bcef81df6258", - "reference": "dc9368fae6ef2ffa57eba80a7410bcef81df6258", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", "shasum": "" }, "require": { - "php": "^7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -881,7 +554,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/master" + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" }, "funding": [ { @@ -889,36 +562,66 @@ "type": "github" } ], - "time": "2020-04-20T06:00:37+00:00" + "time": "2023-02-03T06:57:52+00:00" }, { - "name": "phpunit/php-token-stream", - "version": "4.0.4", + "name": "phpunit/phpunit", + "version": "10.3.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3" + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "c87ae282d17b256d09cfef0eb4f5db2d09cfd36a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3", - "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c87ae282d17b256d09cfef0eb4f5db2d09cfd36a", + "reference": "c87ae282d17b256d09cfef0eb4f5db2d09cfd36a", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": "^7.3 || ^8.0" + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.1", + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-invoker": "^4.0", + "phpunit/php-text-template": "^3.0", + "phpunit/php-timer": "^6.0", + "sebastian/cli-parser": "^2.0", + "sebastian/code-unit": "^2.0", + "sebastian/comparator": "^5.0", + "sebastian/diff": "^5.0", + "sebastian/environment": "^6.0", + "sebastian/exporter": "^5.0", + "sebastian/global-state": "^6.0.1", + "sebastian/object-enumerator": "^5.0", + "sebastian/recursion-context": "^5.0", + "sebastian/type": "^4.0", + "sebastian/version": "^4.0" }, - "require-dev": { - "phpunit/phpunit": "^9.0" + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" }, + "bin": [ + "phpunit" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "10.3-dev" } }, "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], "classmap": [ "src/" ] @@ -930,89 +633,122 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", "keywords": [ - "tokenizer" + "phpunit", + "testing", + "xunit" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master" + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.0" }, "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" } ], - "abandoned": true, - "time": "2020-08-04T08:28:15+00:00" + "time": "2023-08-04T03:56:35+00:00" }, { - "name": "phpunit/phpunit", - "version": "9.0.0", + "name": "sebastian/cli-parser", + "version": "2.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a5be9621b19ee19dca5f150a5b159f48b5389547" + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a5be9621b19ee19dca5f150a5b159f48b5389547", - "reference": "a5be9621b19ee19dca5f150a5b159f48b5389547", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2.0", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.9.1", - "phar-io/manifest": "^1.0.3", - "phar-io/version": "^2.0.1", - "php": "^7.3", - "phpspec/prophecy": "^1.8.1", - "phpunit/php-code-coverage": "^8.0", - "phpunit/php-file-iterator": "^3.0", - "phpunit/php-invoker": "^3.0", - "phpunit/php-text-template": "^2.0", - "phpunit/php-timer": "^3.0", - "sebastian/comparator": "^4.0", - "sebastian/diff": "^4.0", - "sebastian/environment": "^5.0", - "sebastian/exporter": "^4.0", - "sebastian/global-state": "^4.0", - "sebastian/object-enumerator": "^4.0", - "sebastian/resource-operations": "^3.0", - "sebastian/type": "^2.0", - "sebastian/version": "^3.0" + "php": ">=8.1" }, "require-dev": { - "ext-pdo": "*" + "phpunit/phpunit": "^10.0" }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } }, - "bin": [ - "phpunit" + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], + "time": "2024-03-02T07:12:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "9.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], "classmap": [ "src/" ] @@ -1028,43 +764,44 @@ "role": "lead" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.0.0" + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" }, - "time": "2020-02-07T06:56:17+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1086,7 +823,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" }, "funding": [ { @@ -1094,34 +831,36 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2023-02-03T06:59:15+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.8", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1160,7 +899,66 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-18T14:56:07+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68ff824baeae169ec9f2137158ee529584553799" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" }, "funding": [ { @@ -1168,33 +966,33 @@ "type": "github" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2023-12-21T08:37:17+00:00" }, { "name": "sebastian/diff", - "version": "4.0.5", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1226,7 +1024,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" }, "funding": [ { @@ -1234,27 +1033,27 @@ "type": "github" } ], - "time": "2023-05-07T05:35:17+00:00" + "time": "2024-03-02T07:15:17+00:00" }, { "name": "sebastian/environment", - "version": "5.1.5", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-posix": "*" @@ -1262,7 +1061,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -1281,7 +1080,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -1289,7 +1088,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" }, "funding": [ { @@ -1297,34 +1097,34 @@ "type": "github" } ], - "time": "2023-02-03T06:03:51+00:00" + "time": "2024-03-23T08:47:14+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.5", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + "reference": "955288482d97c19a372d3f31006ab3f37da47adf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1366,7 +1166,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" }, "funding": [ { @@ -1374,38 +1175,35 @@ "type": "github" } ], - "time": "2022-09-14T06:03:37+00:00" + "time": "2024-03-02T07:17:12+00:00" }, { "name": "sebastian/global-state", - "version": "4.0.0", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bdb1e7c79e592b8c82cb1699be3c8743119b8a72" + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bdb1e7c79e592b8c82cb1699be3c8743119b8a72", - "reference": "bdb1e7c79e592b8c82cb1699be3c8743119b8a72", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", "shasum": "" }, "require": { - "php": "^7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.0" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1424,42 +1222,48 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/master" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" }, - "time": "2020-02-07T06:11:37+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:19:19+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "4.0.4", + "name": "sebastian/lines-of-code", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -1474,14 +1278,16 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" }, "funding": [ { @@ -1489,32 +1295,34 @@ "type": "github" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2023-12-21T08:38:20+00:00" }, { - "name": "sebastian/object-reflector", - "version": "2.0.4", + "name": "sebastian/object-enumerator", + "version": "5.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1532,11 +1340,11 @@ "email": "sebastian@phpunit.de" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" }, "funding": [ { @@ -1544,32 +1352,32 @@ "type": "github" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2023-02-03T07:08:32+00:00" }, { - "name": "sebastian/recursion-context", - "version": "4.0.5", + "name": "sebastian/object-reflector", + "version": "3.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1585,21 +1393,13 @@ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" }, "funding": [ { @@ -1607,32 +1407,32 @@ "type": "github" } ], - "time": "2023-02-03T06:07:39+00:00" + "time": "2023-02-03T07:06:18+00:00" }, { - "name": "sebastian/resource-operations", - "version": "3.0.3", + "name": "sebastian/recursion-context", + "version": "5.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1648,13 +1448,21 @@ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" }, "funding": [ { @@ -1662,32 +1470,32 @@ "type": "github" } ], - "time": "2020-09-28T06:45:17+00:00" + "time": "2023-02-03T07:05:40+00:00" }, { "name": "sebastian/type", - "version": "2.3.4", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1710,7 +1518,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" }, "funding": [ { @@ -1718,29 +1526,29 @@ "type": "github" } ], - "time": "2021-06-15T12:49:02+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { "name": "sebastian/version", - "version": "3.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1763,7 +1571,7 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" }, "funding": [ { @@ -1771,20 +1579,20 @@ "type": "github" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -1813,7 +1621,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -1821,65 +1629,7 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.11.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", - "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "php": "^7.2 || ^8.0" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.11.0" - }, - "time": "2022-06-03T18:03:27+00:00" + "time": "2024-03-03T12:36:25+00:00" } ], "aliases": [], diff --git a/server/classes/headstart/tests/DispatchingPersistenceTest.php b/server/classes/headstart/tests/DispatchingPersistenceTest.php index 94eb13ca0..954202bbd 100644 --- a/server/classes/headstart/tests/DispatchingPersistenceTest.php +++ b/server/classes/headstart/tests/DispatchingPersistenceTest.php @@ -13,6 +13,11 @@ class DispatchingPersistenceTest extends TestCase { + protected function setUp(): void + { + $this->markTestIncomplete('Skipping because this is no longer used for dispatching'); + } + public function testCreateVisualizationDispatcherToOldPersistence(): void { $oldPersistence = $this->createMock(Persistence::class); diff --git a/server/classes/headstart/tests/PostgresPersistenceTest.php b/server/classes/headstart/tests/PostgresPersistenceTest.php new file mode 100644 index 000000000..5b345ca6a --- /dev/null +++ b/server/classes/headstart/tests/PostgresPersistenceTest.php @@ -0,0 +1,60 @@ +createMock(APIClient::class); + $jsonFilePath = __DIR__ . "/test_data/successfulGetContextResponse.json"; + $jsonStringFromApi = file_get_contents($jsonFilePath); // returns string + $mockResponse = [ + "result" => $jsonStringFromApi, + "httpcode" => 200 + ]; + $apiclient->method("call_persistence")->willReturn($mockResponse); + $persistence = new PostgresPersistence($apiclient); + $response = $persistence->getContext($vis_id); + $this->assertIsArray($response); + } + + public function testWhenDBMissingReturnsAResponseObjectWeCanHandle(): void { + $apiclient = $this->createMock(APIClient::class); + $jsonFilePath = __DIR__ . "/test_data/unsuccessfulGetContextDBHostCannotBeResolved.json"; + $jsonStringFromApi = file_get_contents($jsonFilePath); // returns string + $mockResponse = [ + "result" => $jsonStringFromApi, + "httpcode" => 503 + ]; + $apiclient->method("call_persistence")->willReturn($mockResponse); + $persistence = new PostgresPersistence($apiclient); + $response = $persistence->getContext($vis_id); + var_dump($response); + $this->assertIsArray($response); + } + + public function testWhenVisIDNotInDBReturnsAResponseObjectWeCanHandle(): void { + $apiclient = $this->createMock(APIClient::class); + $jsonFilePath = __DIR__ . "/test_data/unsuccessfulgetContextResponseVisIdNotInDB.json"; + $jsonStringFromApi = file_get_contents($jsonFilePath); // returns string + $mockResponse = [ + "result" => $jsonStringFromApi, + "httpcode" => 200 + ]; + $apiclient->method("call_persistence")->willReturn($mockResponse); + $persistence = new PostgresPersistence($apiclient); + $response = $persistence->getContext($vis_id); + $this->assertIsArray($response); + } +} \ No newline at end of file diff --git a/server/classes/headstart/tests/test_data/successfulGetContextResponse.json b/server/classes/headstart/tests/test_data/successfulGetContextResponse.json new file mode 100644 index 000000000..a51a87e37 --- /dev/null +++ b/server/classes/headstart/tests/test_data/successfulGetContextResponse.json @@ -0,0 +1,7 @@ +{ + "rev_timestamp": "Thu, 12 Sep 2024 10:23:47 GMT", + "rev_vis": "d161dba364a1e8c0468b9c74407e3575", + "vis_params": "{\"id\": \"d161dba364a1e8c0468b9c74407e3575\", \"query\": \"\\\\\\\"climate change\\\\\\\" and impact\", \"service\": \"base\", \"timestamp\": \"Wed, 24 Aug 2022 14:24:13 GMT\", \"params\": \"{\\\"from\\\":\\\"1665-01-01\\\",\\\"to\\\":\\\"2022-08-24\\\",\\\"document_types\\\":[\\\"121\\\"],\\\"sorting\\\":\\\"most-relevant\\\",\\\"min_descsize\\\":\\\"300\\\"}\"}", + "vis_query": "\\\"climate change\\\" and impact", + "vis_title": "base" + } \ No newline at end of file diff --git a/server/classes/headstart/tests/test_data/unsuccessfulGetContextDBHostCannotBeResolved.json b/server/classes/headstart/tests/test_data/unsuccessfulGetContextDBHostCannotBeResolved.json new file mode 100644 index 000000000..03c1e0ac2 --- /dev/null +++ b/server/classes/headstart/tests/test_data/unsuccessfulGetContextDBHostCannotBeResolved.json @@ -0,0 +1,6 @@ +{ + "reason": [ + "database connection error" + ], + "success": false + } \ No newline at end of file diff --git a/server/classes/headstart/tests/test_data/unsuccessfulgetContextResponseVisIdNotInDB.json b/server/classes/headstart/tests/test_data/unsuccessfulgetContextResponseVisIdNotInDB.json new file mode 100644 index 000000000..8a19cdb2f --- /dev/null +++ b/server/classes/headstart/tests/test_data/unsuccessfulgetContextResponseVisIdNotInDB.json @@ -0,0 +1,3 @@ +[ + false +] \ No newline at end of file diff --git a/server/services/getContext.php b/server/services/getContext.php index 109e19a36..91f5e722b 100644 --- a/server/services/getContext.php +++ b/server/services/getContext.php @@ -18,11 +18,27 @@ $revision_context = isset($_GET["revision_context"]) ? library\CommUtils::getParameter($_GET, "revision_context") : false; $apiclient = new headstart\library\APIClient($ini_array); -$postgresPersistence = new \headstart\persistence\PostgresPersistence($apiclient); -$persistence = new \headstart\persistence\DispatchingPersistence($postgresPersistence); +$persistence = new \headstart\persistence\PostgresPersistence($apiclient); +// Remove the calls to this getContext on the persistence object. Replace instead with a getContextResultBuilder that returns a result object +// This should contain the httpStatusCode to pass to the client, the result in string form (some json encoded string) and it should never throw. + +// [thing that formats the response for the user] - [thing that parses responses from the persistence api] - [thing that makes requests to persisent api and handles the network calls etc.] + +// Err... why is the only caller of this having to unpack the array to take the first result? Is someone wrapping this reponse in an array unecessarily? $data = $persistence->getContext($vis_id)[0]; + +/* +It it works +{ + "rev_timestamp": "Thu, 12 Sep 2024 10:23:47 GMT", + "rev_vis": "d161dba364a1e8c0468b9c74407e3575", + "vis_params": "{\"id\": \"d161dba364a1e8c0468b9c74407e3575\", \"query\": \"\\\\\\\"climate change\\\\\\\" and impact\", \"service\": \"base\", \"timestamp\": \"Wed, 24 Aug 2022 14:24:13 GMT\", \"params\": \"{\\\"from\\\":\\\"1665-01-01\\\",\\\"to\\\":\\\"2022-08-24\\\",\\\"document_types\\\":[\\\"121\\\"],\\\"sorting\\\":\\\"most-relevant\\\",\\\"min_descsize\\\":\\\"300\\\"}\"}", + "vis_query": "\\\"climate change\\\" and impact", + "vis_title": "base" +} +*/ $return_data = array("id" => $data["rev_vis"], "query" => $data["vis_query"], "service" => $data["vis_title"], @@ -32,4 +48,5 @@ $return_data = array_merge($return_data, $data["additional_context"]); } $jsonData = json_encode($return_data); +// To investigate: is anyone needing the callback version of this?? library\CommUtils::echoOrCallback($jsonData, $_GET); From 82facbb3c8ff1e7da2aa9554d7626716a7e87322 Mon Sep 17 00:00:00 2001 From: chreman Date: Tue, 17 Dec 2024 01:04:32 +0100 Subject: [PATCH 08/20] add some more comments --- server/services/getContext.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/services/getContext.php b/server/services/getContext.php index 109e19a36..4e70eb558 100644 --- a/server/services/getContext.php +++ b/server/services/getContext.php @@ -23,6 +23,10 @@ $data = $persistence->getContext($vis_id)[0]; +// if e.g. the db host is missing, error handling should happen here +// we should return a JSON with an error message instead +error_log("Data in getContext.php: " . print_r($data, true)); +// is the database connection error maybe swallowed here? No, but it is not handled either $return_data = array("id" => $data["rev_vis"], "query" => $data["vis_query"], "service" => $data["vis_title"], @@ -32,4 +36,5 @@ $return_data = array_merge($return_data, $data["additional_context"]); } $jsonData = json_encode($return_data); +// in case of db host missing error, it returns HTML from the warnings, and a JSON with null values library\CommUtils::echoOrCallback($jsonData, $_GET); From 07dd70cd26d28cfc05f28a5de7ec8a0a880b265f Mon Sep 17 00:00:00 2001 From: chreman Date: Tue, 17 Dec 2024 19:44:11 +0100 Subject: [PATCH 09/20] php services cleanup --- server/services/GSheetUpdateAvailable.php | 44 ----- server/services/addBookmark.php | 26 --- server/services/autoViper.php | 208 ---------------------- server/services/createHeadstart.php | 133 -------------- server/services/createNewGSheet.php | 45 ----- server/services/getBookmarks.php | 28 --- server/services/getGSheetsMap.php | 63 ------- server/services/markProjectChanged.php | 18 -- server/services/removeBookmark.php | 24 --- server/services/searchDOAJ.php | 23 --- server/services/searchPLOS.php | 22 --- server/services/searchTRIPLE.php | 36 ---- server/services/staticFiles.php | 29 --- server/services/updateGSheetsMap.php | 44 ----- server/services/updateViper.php | 186 ------------------- server/services/writeActionToLog.php | 26 --- 16 files changed, 955 deletions(-) delete mode 100644 server/services/GSheetUpdateAvailable.php delete mode 100644 server/services/addBookmark.php delete mode 100644 server/services/autoViper.php delete mode 100644 server/services/createHeadstart.php delete mode 100644 server/services/createNewGSheet.php delete mode 100644 server/services/getBookmarks.php delete mode 100644 server/services/getGSheetsMap.php delete mode 100644 server/services/markProjectChanged.php delete mode 100644 server/services/removeBookmark.php delete mode 100644 server/services/searchDOAJ.php delete mode 100644 server/services/searchPLOS.php delete mode 100644 server/services/searchTRIPLE.php delete mode 100644 server/services/staticFiles.php delete mode 100644 server/services/updateGSheetsMap.php delete mode 100644 server/services/updateViper.php delete mode 100644 server/services/writeActionToLog.php diff --git a/server/services/GSheetUpdateAvailable.php b/server/services/GSheetUpdateAvailable.php deleted file mode 100644 index 37bdfc2af..000000000 --- a/server/services/GSheetUpdateAvailable.php +++ /dev/null @@ -1,44 +0,0 @@ - $vis_id, "details" => false, "context" => true)); - $res = $apiclient->call_persistence("getLastVersion", $payload); - if ($res["httpcode"] != 200) { - library\CommUtils::echoOrCallback($res, $_GET); - } else { - $data = json_decode($res["result"], true); - $rev_data = json_decode($data["rev_data"], true); - $timestamp_old = $rev_data["last_update"]; - $update_available = ($timestamp_old != $gsheet_last_updated) ? true : false; - $return_data = array("update_available" => $update_available); - $jsonData = json_encode($return_data); - library\CommUtils::echoOrCallback($jsonData, $_GET); - } -} else { - $data = $persistence->getLastVersion($vis_id, $details = false, $context = true)[0]; - $rev_data = json_decode($data["rev_data"], true); - $timestamp_old = $rev_data["last_update"]; - $update_available = ($timestamp_old != $gsheet_last_updated) ? true : false; - $return_data = array("update_available" => $update_available); - $jsonData = json_encode($return_data); - library\CommUtils::echoOrCallback($jsonData, $_GET); -} - -?> diff --git a/server/services/addBookmark.php b/server/services/addBookmark.php deleted file mode 100644 index ef2e68d33..000000000 --- a/server/services/addBookmark.php +++ /dev/null @@ -1,26 +0,0 @@ -establishConnection(); -$bookmarking_data = $connection->addPersonalBookmark($user_id, $conference_id); - -$jsonData = json_encode($bookmarking_data); - -library\CommUtils::echoOrCallback($jsonData, $_GET); diff --git a/server/services/autoViper.php b/server/services/autoViper.php deleted file mode 100644 index c04c8ad82..000000000 --- a/server/services/autoViper.php +++ /dev/null @@ -1,208 +0,0 @@ -getNamespaces(true); - $xml->registerXPathNamespace('oaf', 'http://namespace.openaire.eu/oaf'); - $xml->registerXPathNamespace('dri', 'http://www.driver-repository.eu/namespace/dri'); - $xml->registerXPathNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance'); - $projects = $xml->xpath("//result//oaf:project"); - $project_ids = $xml->xpath("//code"); - $funders = $xml->xpath("//fundingtree/funder/shortname"); - $funderstr = array(); - foreach($funders as $f) { - $funderstr[] = (string)$f; - } - $obj_ids = $xml->xpath("//header//dri:objIdentifier"); - $obj_idstr = array(); - foreach($obj_ids as $obj_id) { - $obj_idstr[] = (string)$obj_id; - } - $proj_idstr = array(); - foreach($project_ids as $proj_id) { - $proj_idstr[] = (string)$proj_id; - } - $parsed_projects = array_combine($proj_idstr, $funderstr); - $projid2objid = array_combine($proj_idstr, $obj_idstr); - $objid2projid = array_combine($obj_idstr, $proj_idstr); - return array($funderstr[0], $parsed_projects, $projid2objid, $objid2projid); -} - -function filterProjects($resource_counts) { - $filtered_projects = array(); - foreach($resource_counts as $obj_id => $rc) { - if ($rc["publications"] + $rc["datasets"] > 0) { - $filtered_projects[] = $obj_id; - } - } - return $filtered_projects; -} - -function getProjectsbyFunder($funderparams) { - $funder = $funderparams[0]; - $startYear = $funderparams[1]; - $endYear = $funderparams[2]; - $participantCountries = $funderparams[3]; - $participantAcronyms = $funderparams[4]; - - $url = 'http://api.openaire.eu/search/projects?format=xml' - . "&funder=" . $funder - . "&size=" . "1000" - . "&startYear=" . $startYear - . "&endYear=" . $endYear; - if ($participantCountries) { - $url = $url . "&participantCountries=" . $participantCountries; - } - if ($participantAcronyms) { - $url = $url . "&participantAcronyms=" . $participantAcronyms; - } - $ch = curl_init(); - - curl_setopt_array($ch, array( - CURLOPT_RETURNTRANSFER => 1, - CURLOPT_URL => $url - )); - - $response = curl_exec($ch); - return $response; -} - - -# functions for getting resources - -function createAndAddMultiHandle($url, &$multi_array, &$mh, $id) { - $multi_array[$id] = curl_init(); - curl_setopt($multi_array[$id], CURLOPT_URL, $url); - curl_setopt($multi_array[$id], CURLOPT_RETURNTRANSFER, 1); - curl_multi_add_handle($mh, $multi_array[$id]); -} - -function getResourceCounts($parsed_response) { - $parsed_projects = $parsed_response[1]; - $projid2objid = $parsed_response[2]; - $multi_array = array(); - $results = array(); - $mh = curl_multi_init(); - foreach ($parsed_projects as $project_id => $funder) { - $url_publications = "http://api.openaire.eu/search/publications?projectID=" - . urlencode($project_id) - . "&funder=" . $funder . "&format=json&size=0"; - $url_datasets = "http://api.openaire.eu/search/datasets?projectID=" - . urlencode($project_id) - . "&funder=" . $funder . "&format=json&size=0"; - - $id = $projid2objid[$project_id]; - createAndAddMultiHandle($url_publications, $multi_array, $mh, "p_" . $id); - createAndAddMultiHandle($url_datasets, $multi_array, $mh, "d_" . $id); - } - $index=null; - do { - curl_multi_exec($mh,$index); - } while($index > 0); - - foreach($multi_array as $id => $ch) { - $results[$id] = curl_multi_getcontent($ch); - curl_multi_remove_handle($mh, $ch); - } - - curl_multi_close($mh); - - $return_array = array(); - - foreach($results as $id => $result) { - $prefix = substr($id, 0, 2); - $obj_id = substr($id, 2); - - $result_array = json_decode($result, true); - - if($prefix == "p_") { - $return_array[$obj_id]["publications"] = $result_array["response"]["header"]["total"]["$"]; - } else if($prefix == "d_") { - $return_array[$obj_id]["datasets"] = $result_array["response"]["header"]["total"]["$"]; - } - } - return $return_array; - -} - -?> diff --git a/server/services/createHeadstart.php b/server/services/createHeadstart.php deleted file mode 100644 index 8e74feb81..000000000 --- a/server/services/createHeadstart.php +++ /dev/null @@ -1,133 +0,0 @@ -performCalculationAndReturnOutputAsJSON($metadata_filename, $cooc_filename); - -fclose($metadata_file); -fclose($cooc_file); - -$output_json = end($output); - -$output_json = iconv(mb_detect_encoding($output_json), "UTF-8", $output_json); - -$output_json = html_entity_decode(preg_replace("//", "&#x\\1;", $output_json), ENT_NOQUOTES, 'UTF-8'); - -if (!library\Toolkit::isJSON($output_json)) { - echo "Sorry! Something went wrong - most likely we haven't found any documents matching your search term. Please go back and try again."; -// echo $output_json; - return; -} - -$result = json_decode($output_json, true); - -$naming = new \headstart\preprocessing\naming\KeywordNaming($ini_array); -$naming->performNamingTfIdf($result, 3, "area_uri", "keywords", ",", null); - -echo json_encode($result); - -function calculateCooccurrences($array, $key) { - $working = array(); - $output = array(); - - foreach ($array as $entry) { - - $id = $entry["id"]; - $keywords = explode(",", $entry[$key]); - - array_walk($keywords, function(&$value, &$key) { - $value = trim($value); - }); - - $working[$id] = $keywords; - } - - - $row = 0; - $keys = array_keys($working); - foreach($working as $id => $keywords) { - - for ($corow = $row; $corow < count($working); $corow++) { - $id2 = $keys[$corow]; - $intersect = array_intersect($keywords, $working[$id2]); - - if ($corow == $row) { - $output[] = array("id1" => $id, "id2" => $id2, "count" => count($intersect)); - } else { - $output[] = array("id1" => $id, "id2" => $id2, "count" => count($intersect)); - $output[] = array("id1" => $id2, "id2" => $id, "count" => count($intersect)); - } - - $corow++; - } - - $row++; - } - - return $output; - -} - -function entities_to_unicode($str) { - $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8'); - $str = preg_replace_callback("/(&#[0-9]+;)/", function($m) { return mb_convert_encoding($m[1], "UTF-8", "HTML-ENTITIES"); }, $str); - return $str; -} - -?> \ No newline at end of file diff --git a/server/services/createNewGSheet.php b/server/services/createNewGSheet.php deleted file mode 100644 index 9d7fc3f5b..000000000 --- a/server/services/createNewGSheet.php +++ /dev/null @@ -1,45 +0,0 @@ - $sheet_name, - "project_name" => $project_name, - "main_curator_email" => $main_curator_email, - "knowledge_base_template_id" => $knowledge_base_template_id)); -$res = $apiclient->call_api("/gsheets" . "/createKnowledgebase", $payload); -if ($res["httpcode"] != 200) { - echo json_encode($res); -} else { - $result = json_decode($res["result"], true); - echo $result; -} - -?> diff --git a/server/services/getBookmarks.php b/server/services/getBookmarks.php deleted file mode 100644 index 24fb550d0..000000000 --- a/server/services/getBookmarks.php +++ /dev/null @@ -1,28 +0,0 @@ -establishConnection(); -$bookmarking_data = $connection->getPersonalBookmarks($user_id, $conference_id); -$recommendation_data = $connection->getPersonalRecommendations($user_id, $conference_id); -$bookmarking_data_all = $connection->getConferenceBookmarks($conference_id); - -$data = array("bookmarks" => $bookmarking_data, "recommendations" => $recommendation_data, "bookmarks_all" => $bookmarking_data_all); - -$jsonData = json_encode($data); - -library\CommUtils::echoOrCallback($jsonData, $_GET); diff --git a/server/services/getGSheetsMap.php b/server/services/getGSheetsMap.php deleted file mode 100644 index 896d9d356..000000000 --- a/server/services/getGSheetsMap.php +++ /dev/null @@ -1,63 +0,0 @@ - $vis_id, "details" => false, "context" => true)); - $res = $apiclient->call_persistence("getLastVersion", $payload); - if ($res["httpcode"] != 200) { - library\CommUtils::echoOrCallback($res, $_GET); - } else { - $data = json_decode($res["result"], true); - $rev_data = json_decode($data["rev_data"], true); - $context = array("id" => $data["rev_vis"], - "query" => $data["vis_query"], - "service" => $data["vis_title"], - "timestamp" => $data["rev_timestamp"], - "params" => $data["vis_params"], - "sheet_id" => $rev_data["sheet_id"], - "last_update" => $rev_data["last_update"]); - if (array_key_exists("additional_context", $rev_data)) { - $context = array_merge($context, $rev_data["additional_context"]); - } - $return_data = array("context" => $context, - "data" => $rev_data["data"], - "errors" => $rev_data["errors"]); - $jsonData = json_encode($return_data); - library\CommUtils::echoOrCallback($jsonData, $_GET); - } -} else { - $data = $persistence->getLastVersion($vis_id, $details = false, $context = true)[0]; - $rev_data = json_decode($data["rev_data"], true); - $context = array("id" => $data["rev_vis"], - "query" => $data["vis_query"], - "service" => $data["vis_title"], - "timestamp" => $data["rev_timestamp"], - "params" => $data["vis_params"], - "sheet_id" => $rev_data["sheet_id"], - "last_update" => $rev_data["last_update"]); - if (array_key_exists("additional_context", $rev_data)) { - $context = array_merge($context, $rev_data["additional_context"]); - } - $return_data = array("context" => $context, - "data" => $rev_data["data"], - "errors" => $rev_data["errors"]); - $jsonData = json_encode($return_data); - library\CommUtils::echoOrCallback($jsonData, $_GET); -} diff --git a/server/services/markProjectChanged.php b/server/services/markProjectChanged.php deleted file mode 100644 index 391f0b13b..000000000 --- a/server/services/markProjectChanged.php +++ /dev/null @@ -1,18 +0,0 @@ -markVisChanged($vis_id); \ No newline at end of file diff --git a/server/services/removeBookmark.php b/server/services/removeBookmark.php deleted file mode 100644 index 5c3e988f8..000000000 --- a/server/services/removeBookmark.php +++ /dev/null @@ -1,24 +0,0 @@ -establishConnection(); -$bookmarking_data = $connection->removePersonalBookmark($user_id, $conference_id); - -$jsonData = json_encode($bookmarking_data); - -library\CommUtils::echoOrCallback($jsonData, $_GET); diff --git a/server/services/searchDOAJ.php b/server/services/searchDOAJ.php deleted file mode 100644 index b221cb9ea..000000000 --- a/server/services/searchDOAJ.php +++ /dev/null @@ -1,23 +0,0 @@ - diff --git a/server/services/searchPLOS.php b/server/services/searchPLOS.php deleted file mode 100644 index b5f9822fd..000000000 --- a/server/services/searchPLOS.php +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/server/services/searchTRIPLE.php b/server/services/searchTRIPLE.php deleted file mode 100644 index 41a9bc58a..000000000 --- a/server/services/searchTRIPLE.php +++ /dev/null @@ -1,36 +0,0 @@ - diff --git a/server/services/staticFiles.php b/server/services/staticFiles.php deleted file mode 100644 index 26b6be545..000000000 --- a/server/services/staticFiles.php +++ /dev/null @@ -1,29 +0,0 @@ -'edu1', - 'file'=>"/data/educational-technology.csv" - ), - array( - 'title'=>'edu2', - 'file'=>"/data/edu2.csv" - ), - // array( - // 'title'=>'edu3', - // 'file'=>"/data/edu3.csv" - // ), - // array( - // 'title'=>'edu4', - // 'file'=>"/data/edu4.csv" - // ), - array( - 'title'=>'edu5', - 'file'=>"/data/edu5.csv") - ); - -echo json_encode($arr); - -exit(); -?> \ No newline at end of file diff --git a/server/services/updateGSheetsMap.php b/server/services/updateGSheetsMap.php deleted file mode 100644 index 333ffcaac..000000000 --- a/server/services/updateGSheetsMap.php +++ /dev/null @@ -1,44 +0,0 @@ - $dirty_query, "sheet_id" => $sheet_id, "sheet_range" => "Resources!A1:AG200"); -if(isset($last_update)) { - $params["last_update"] = $last_update; -} - -$result = search("gsheets", $dirty_query - , $params, array("sheet_id") - , false - , false, null - , $sheet_id, false); - -echo $result; - -?> diff --git a/server/services/updateViper.php b/server/services/updateViper.php deleted file mode 100644 index 2a7768790..000000000 --- a/server/services/updateViper.php +++ /dev/null @@ -1,186 +0,0 @@ -getUpdateMaps($vis_changed); - $updateCandidates = array(); - foreach($maps as $map) { - $params = json_decode($map['vis_params'], true); - $vis_id = $map['vis_id']; - $updateCandidates[$vis_id]['vis_query'] = $map['vis_query']; - $updateCandidates[$vis_id]['vis_params'] = $params; - $updateCandidates[$vis_id]['vis_changed_timestamp'] = $map['vis_changed_timestamp']; - } - return $updateCandidates; -} - -function getCandidatesByObjectIDs($vis_changed, $persistence, $object_ids) { - # get candidates via DB query - # object IDs needs to be a comma separated list of IDs - $obj_ids = array(); - foreach($object_ids as $obj_id){ - $obj_ids[] = $obj_id[0]; - } - $maps = $persistence->getUpdateMaps($vis_changed); - $updateCandidates = array(); - foreach($maps as $map) { - $params = json_decode($map['vis_params'], true); - $obj_id = $params['obj_id']; - if (in_array($obj_id, $obj_ids)) { - $vis_id = $map['vis_id']; - $updateCandidates[$vis_id]['vis_query'] = $map['vis_query']; - $updateCandidates[$vis_id]['vis_params'] = $params; - $updateCandidates[$vis_id]['vis_changed_timestamp'] = $map['vis_changed_timestamp']; - } - } - return $updateCandidates; -} - -function getCandidatesByFunderProject($vis_changed, $persistence, $funderproject) { - # get candidates via DB query - $updateCandidates = array(); - $maps = $persistence->getUpdateMaps($vis_changed); - foreach($funderproject as $fp){ - foreach($maps as $map) { - $params = json_decode($map['vis_params'], true); - if ($params['funder'] == $fp[0] and $params['project_id'] == $fp[1]) { - $vis_id = $map['vis_id']; - $updateCandidates[$vis_id]['vis_query'] = $map['vis_query']; - $updateCandidates[$vis_id]['vis_params'] = $params; - $updateCandidates[$vis_id]['vis_changed_timestamp'] = $map['vis_changed_timestamp']; - } - } - } - return $updateCandidates; -} - -function runUpdate($acronymtitle, $params) { - // echo "$acronymtitle"; - // echo "\n"; - $decoded_params = decodeParams($params); - $post_params = $decoded_params[0]; - $param_types = $decoded_params[1]; - $params_for_id = array("project_id", "funder"); - $result = search("openaire", $acronymtitle, - $params, $param_types, - ";", null, false, false, $params_for_id); - echo $result; -} - -function checkFlagAge($vis_id, $vis_changed_timestamp, $persistence) { - $timestamp = strtotime($vis_changed_timestamp); - $curtime = time(); - if(($curtime-$timestamp) > 86400) { - $persistence->resetFlag($vis_id); - } -} - -function runUpdates($updateCandidates, $persistence) { - foreach($updateCandidates as $vis_id => $map) { - $params = $map['vis_params']; - $acronymtitle = $map['vis_query']; - $vis_changed_timestamp = $map['vis_changed_timestamp']; - runUpdate($acronymtitle, $params); - checkFlagAge($vis_id, $vis_changed_timestamp, $persistence); - sleep(10); - } -} - -function decodeParams($paramString) { - $post_params = array(); - $param_types = array(); - foreach($paramString as $x => $x_value) { - $post_params[] = $x_value; - $param_types[] = $x; - } - return array($post_params, $param_types); -} - -?> diff --git a/server/services/writeActionToLog.php b/server/services/writeActionToLog.php deleted file mode 100644 index c8af689d5..000000000 --- a/server/services/writeActionToLog.php +++ /dev/null @@ -1,26 +0,0 @@ -$_SERVER['REMOTE_ADDR'], "user_agent"=>$_SERVER['HTTP_USER_AGENT'], "user_id"=>$user_id); - -$logData = array_merge($serverData, $_GET); - -if($_POST != null) - $logData = array_merge($logData, $_POST); - -$logger = new logger\FileLogger(dirname(__FILE__) . '/../../log/', null); -$logger->writeToLog($logData); - -$jsonData = json_encode($logData); - -library\CommUtils::echoOrCallback($jsonData, $_GET["jsoncallback"]); - - From 1963fece4b7a4a5702c24e01a03ebd695d9f61ea Mon Sep 17 00:00:00 2001 From: chreman Date: Tue, 17 Dec 2024 19:45:23 +0100 Subject: [PATCH 10/20] first draft of getContextResultBuilder --- .../classes/headstart/library/APIClient.php | 5 +++ .../classes/headstart/library/CommUtils.php | 1 + .../library/getContextResultBuilder.php | 37 +++++++++++++++++++ server/services/getContext.php | 27 ++++++++------ server/services/search.php | 21 ++++++----- server/workers/persistence/src/persistence.py | 5 ++- 6 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 server/classes/headstart/library/getContextResultBuilder.php diff --git a/server/classes/headstart/library/APIClient.php b/server/classes/headstart/library/APIClient.php index e5d9d0612..f3528a27d 100644 --- a/server/classes/headstart/library/APIClient.php +++ b/server/classes/headstart/library/APIClient.php @@ -53,6 +53,9 @@ public function call_persistence($endpoint, $payload) { return $res; } catch (Exception $e) { + // what happens here is instead of bubbling the error up, + // it is caught and we fake a response that looks like an error + // because of the hardcoded reason we loose the original error information $res = array("status"=>"error", "httpcode"=>500, "reason"=>array("unexpected data processing error")); @@ -71,6 +74,8 @@ public function handle_api_errors($res) { error_log(("Trying to handle API errors: " . print_r($res, true))); $res["status"] = "error"; if ($res["httpcode"] == 503) { + // we had a 503 for the database connection error + // this implementation actively suppresses the reason by resetting to an empty array $res["reason"] = array(); } if (!array_key_exists("reason", $res)) { diff --git a/server/classes/headstart/library/CommUtils.php b/server/classes/headstart/library/CommUtils.php index b59fdd945..2f69b5942 100644 --- a/server/classes/headstart/library/CommUtils.php +++ b/server/classes/headstart/library/CommUtils.php @@ -53,6 +53,7 @@ public static function call_api($route, $payload) { curl_close($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($result === false) + // in this case, the curl call result is false and $result is a string with the CURL error $result = curl_error($ch); return array("result" => $result, "httpcode" => $httpcode); } diff --git a/server/classes/headstart/library/getContextResultBuilder.php b/server/classes/headstart/library/getContextResultBuilder.php new file mode 100644 index 000000000..b32f2ee8e --- /dev/null +++ b/server/classes/headstart/library/getContextResultBuilder.php @@ -0,0 +1,37 @@ +persistence = $persistence; + } + + public function getContext($vis_id) { + $data = $this->persistence->getContext($vis_id); + $return_data = array("id" => $data["rev_vis"], + "query" => $data["vis_query"], + "service" => $data["vis_title"], + "timestamp" => $data["rev_timestamp"], + "params" => $data["vis_params"]); + if (array_key_exists("additional_context", $data)) { + $return_data = array_merge($return_data, $data["additional_context"]); + } + $result = json_encode($return_data); + return $result; + } + +} \ No newline at end of file diff --git a/server/services/getContext.php b/server/services/getContext.php index 91f5e722b..ab14720e0 100644 --- a/server/services/getContext.php +++ b/server/services/getContext.php @@ -7,6 +7,7 @@ require_once dirname(__FILE__) . '/../classes/headstart/library/CommUtils.php'; require_once dirname(__FILE__) . '/../classes/headstart/library/Toolkit.php'; require_once dirname(__FILE__) . '/../classes/headstart/library/APIClient.php'; +require_once dirname(__FILE__) . '/../classes/headstart/library/getContextResultBuilder.php'; use headstart\library; @@ -23,11 +24,13 @@ // Remove the calls to this getContext on the persistence object. Replace instead with a getContextResultBuilder that returns a result object // This should contain the httpStatusCode to pass to the client, the result in string form (some json encoded string) and it should never throw. +$getContextResultBuilder = new \headstart\library\getContextResultBuilder($persistence); // [thing that formats the response for the user] - [thing that parses responses from the persistence api] - [thing that makes requests to persisent api and handles the network calls etc.] // Err... why is the only caller of this having to unpack the array to take the first result? Is someone wrapping this reponse in an array unecessarily? -$data = $persistence->getContext($vis_id)[0]; +// $data = $persistence->getContext($vis_id)[0]; +$result = $getContextResultBuilder->getContext($vis_id); /* It it works @@ -39,14 +42,16 @@ "vis_title": "base" } */ -$return_data = array("id" => $data["rev_vis"], - "query" => $data["vis_query"], - "service" => $data["vis_title"], - "timestamp" => $data["rev_timestamp"], - "params" => $data["vis_params"]); -if (array_key_exists("additional_context", $data)) { - $return_data = array_merge($return_data, $data["additional_context"]); -} -$jsonData = json_encode($return_data); +// $return_data = array("id" => $data["rev_vis"], +// "query" => $data["vis_query"], +// "service" => $data["vis_title"], +// "timestamp" => $data["rev_timestamp"], +// "params" => $data["vis_params"]); +// if (array_key_exists("additional_context", $data)) { +// $return_data = array_merge($return_data, $data["additional_context"]); +// } +// $jsonData = json_encode($return_data); // To investigate: is anyone needing the callback version of this?? -library\CommUtils::echoOrCallback($jsonData, $_GET); +// meaning, can this be simplified to just echo $result; +// library\CommUtils::echoOrCallback($result, $_GET); +echo $result; diff --git a/server/services/search.php b/server/services/search.php index 4fc9df002..ef8313ba4 100644 --- a/server/services/search.php +++ b/server/services/search.php @@ -73,8 +73,8 @@ function search($service, $dirty_query ? (cleanQuery($dirty_query, $transform_query_tolowercase, $add_slashes)) : ($dirty_query); - $postgresPersistence = new \headstart\persistence\PostgresPersistence($apiclient); - $persistence = new \headstart\persistence\DispatchingPersistence($postgresPersistence); + $persistence = new \headstart\persistence\PostgresPersistence($apiclient); + // $persistence = new \headstart\persistence\DispatchingPersistence($postgresPersistence); // todo: move back into own function once error handling is refactored if ($service == "openaire") { @@ -113,8 +113,17 @@ function search($service, $dirty_query if($retrieve_cached_map) { $last_version = $persistence->getLastVersion($unique_id, false, false); + error_log("search.php: last_version call returned " . print_r($last_version, true)); + // check if last_version call has httpcode, this is not always the case for return values + // then check if success-status of last_version call is false + if (isset($last_version["result"]["httpcode"]) && $last_version["result"]["httpcode"] != 200) { + error_log("search.php: last_version call failed with http code " . $last_version["result"]["httpcode"]); + error_log("search.php: last_version call failed with result " . $last_version["result"]); + echo json_encode($last_version["result"]); + return; + } + if ($last_version != null && $last_version != "null" && $last_version != false) { - error_log("search.php: last_version call returned " . print_r($last_version, true)); // for example, non-existant vis_id is handled here, which looks like [False] echo json_encode(array("query" => $query, "id" => $unique_id, "status" => "success")); return; @@ -122,12 +131,6 @@ function search($service, $dirty_query //todo: log output of $last_version // log to docker logs - // check if success-status of last_version call is false - if ($last_version["httpcode"] != 200) { - error_log("search.php: last_version call failed with http code " . $last_version["httpcode"]); - error_log("search.php: last_version call failed with result " . $last_version["result"]); - return $last_version["result"]; - } } $payload = json_encode($post_params); diff --git a/server/workers/persistence/src/persistence.py b/server/workers/persistence/src/persistence.py index 7017ddb69..076d66877 100644 --- a/server/workers/persistence/src/persistence.py +++ b/server/workers/persistence/src/persistence.py @@ -292,6 +292,7 @@ def post(self, database): @persistence_ns.route('/getContext/') +# this should be a GET request instead class getContext(Resource): @persistence_ns.produces(["application/json"]) @@ -315,10 +316,12 @@ def post(self, database): result = {'success': False, 'reason': ["database connection error"]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), - 500, + 503, headers) except Exception as e: persistence_ns.logger.error("getContext: %s" % str(e), exc_info=True) + # do we want to changes result reason to be more generic, but not open ended? + # at least we could map it to a specific error code/message on the fail page result = {'success': False, 'reason': [str(e)]} headers = {'ContentType': 'application/json'} return make_response(jsonify(result), From f135059e1092aa21f9d45483fac7ec63f233511c Mon Sep 17 00:00:00 2001 From: chreman Date: Tue, 17 Dec 2024 20:58:36 +0100 Subject: [PATCH 11/20] first working draft of convoluted error handling logic in search.php --- .../classes/headstart/library/APIClient.php | 2 +- .../library/getContextResultBuilder.php | 3 ++- server/services/search.php | 20 ++++++++++++------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/server/classes/headstart/library/APIClient.php b/server/classes/headstart/library/APIClient.php index f3528a27d..a78701c38 100644 --- a/server/classes/headstart/library/APIClient.php +++ b/server/classes/headstart/library/APIClient.php @@ -76,7 +76,7 @@ public function handle_api_errors($res) { if ($res["httpcode"] == 503) { // we had a 503 for the database connection error // this implementation actively suppresses the reason by resetting to an empty array - $res["reason"] = array(); + // $res["reason"] = array(); } if (!array_key_exists("reason", $res)) { $res["reason"] = array(); diff --git a/server/classes/headstart/library/getContextResultBuilder.php b/server/classes/headstart/library/getContextResultBuilder.php index b32f2ee8e..c1c1d88e9 100644 --- a/server/classes/headstart/library/getContextResultBuilder.php +++ b/server/classes/headstart/library/getContextResultBuilder.php @@ -21,7 +21,8 @@ public function __construct($persistence) { } public function getContext($vis_id) { - $data = $this->persistence->getContext($vis_id); + // TODO: remove the [0] unpacking from array + $data = $this->persistence->getContext($vis_id)[0]; $return_data = array("id" => $data["rev_vis"], "query" => $data["vis_query"], "service" => $data["vis_title"], diff --git a/server/services/search.php b/server/services/search.php index ef8313ba4..ad9e2fbbf 100644 --- a/server/services/search.php +++ b/server/services/search.php @@ -115,14 +115,20 @@ function search($service, $dirty_query $last_version = $persistence->getLastVersion($unique_id, false, false); error_log("search.php: last_version call returned " . print_r($last_version, true)); // check if last_version call has httpcode, this is not always the case for return values - // then check if success-status of last_version call is false - if (isset($last_version["result"]["httpcode"]) && $last_version["result"]["httpcode"] != 200) { - error_log("search.php: last_version call failed with http code " . $last_version["result"]["httpcode"]); - error_log("search.php: last_version call failed with result " . $last_version["result"]); - echo json_encode($last_version["result"]); - return; + // then check if success-status of last_version call is false + if (is_array($last_version) && is_array(($last_version[0]))) { + $last_version = $last_version[0]; + if (array_key_exists("httpcode", $last_version) && $last_version["httpcode"] != 200) { + $result = json_decode($last_version["result"], true); + $httpcode = $last_version["httpcode"]; + error_log("search.php: last_version call failed with http code " . $httpcode); + error_log("search.php: last_version call failed with result " . print_r($result, true)); + echo json_encode($result); + return; + } } - + // TODO: This and the previous if are not mutually exclusive, so the second if should be an else if + // and also it should be refactored to a function that returns the result or throws an exception if ($last_version != null && $last_version != "null" && $last_version != false) { // for example, non-existant vis_id is handled here, which looks like [False] echo json_encode(array("query" => $query, "id" => $unique_id, "status" => "success")); From f7b427cd374c60bf5235014e0b6ce3dfcb8fba76 Mon Sep 17 00:00:00 2001 From: Thomas Arrow Date: Mon, 16 Dec 2024 17:23:23 +0000 Subject: [PATCH 12/20] run phpunit82 --migrate-configuration --- server/classes/headstart/phpunit.xml | 32 +++++++++--------------- server/classes/headstart/phpunit.xml.bak | 22 ++++++++++++++++ 2 files changed, 34 insertions(+), 20 deletions(-) create mode 100644 server/classes/headstart/phpunit.xml.bak diff --git a/server/classes/headstart/phpunit.xml b/server/classes/headstart/phpunit.xml index ed664e150..d33ec4e22 100644 --- a/server/classes/headstart/phpunit.xml +++ b/server/classes/headstart/phpunit.xml @@ -1,22 +1,14 @@ - - - - tests - - - - - - src - - + + + + + tests + + + + + src + + diff --git a/server/classes/headstart/phpunit.xml.bak b/server/classes/headstart/phpunit.xml.bak new file mode 100644 index 000000000..ed664e150 --- /dev/null +++ b/server/classes/headstart/phpunit.xml.bak @@ -0,0 +1,22 @@ + + + + + tests + + + + + + src + + + From e9d4c73613620768cde885fc85d40b7f108a1248 Mon Sep 17 00:00:00 2001 From: Thomas Arrow Date: Mon, 16 Dec 2024 17:35:08 +0000 Subject: [PATCH 13/20] refactor common testSetup --- .../tests/PostgresPersistenceTest.php | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/server/classes/headstart/tests/PostgresPersistenceTest.php b/server/classes/headstart/tests/PostgresPersistenceTest.php index 5b345ca6a..485c1b8e0 100644 --- a/server/classes/headstart/tests/PostgresPersistenceTest.php +++ b/server/classes/headstart/tests/PostgresPersistenceTest.php @@ -16,45 +16,41 @@ class PostgresPersistenceTest extends TestCase { public function testThatInSuccesfulConditionsReturnsAResponseObjectWeCanHandle(): void { - $apiclient = $this->createMock(APIClient::class); - $jsonFilePath = __DIR__ . "/test_data/successfulGetContextResponse.json"; - $jsonStringFromApi = file_get_contents($jsonFilePath); // returns string - $mockResponse = [ - "result" => $jsonStringFromApi, - "httpcode" => 200 - ]; - $apiclient->method("call_persistence")->willReturn($mockResponse); + $apiclient = $this->getMockedApiclient("successfulGetContextResponse.json", 200); $persistence = new PostgresPersistence($apiclient); + $vis_id = "asdfasdf"; $response = $persistence->getContext($vis_id); + $this->assertIsArray($response); } public function testWhenDBMissingReturnsAResponseObjectWeCanHandle(): void { - $apiclient = $this->createMock(APIClient::class); - $jsonFilePath = __DIR__ . "/test_data/unsuccessfulGetContextDBHostCannotBeResolved.json"; - $jsonStringFromApi = file_get_contents($jsonFilePath); // returns string - $mockResponse = [ - "result" => $jsonStringFromApi, - "httpcode" => 503 - ]; - $apiclient->method("call_persistence")->willReturn($mockResponse); + $apiclient = $this->getMockedApiclient("unsuccessfulGetContextDBHostCannotBeResolved.json", 503); $persistence = new PostgresPersistence($apiclient); + $vis_id = "asdfasdf"; $response = $persistence->getContext($vis_id); - var_dump($response); + $this->assertIsArray($response); } public function testWhenVisIDNotInDBReturnsAResponseObjectWeCanHandle(): void { + $apiclient = $this->getMockedApiclient("unsuccessfulgetContextResponseVisIdNotInDB.json", 200); + $persistence = new PostgresPersistence($apiclient); + $vis_id = "asdfasdf"; + $response = $persistence->getContext($vis_id); + + $this->assertIsArray($response); + } + + private function getMockedApiclient(string $jsonFileName, int $statusCode): Apiclient { $apiclient = $this->createMock(APIClient::class); - $jsonFilePath = __DIR__ . "/test_data/unsuccessfulgetContextResponseVisIdNotInDB.json"; - $jsonStringFromApi = file_get_contents($jsonFilePath); // returns string + $jsonFilePath = __DIR__ . "/test_data/" . $jsonFileName; + $jsonStringFromApi = file_get_contents($jsonFilePath); $mockResponse = [ "result" => $jsonStringFromApi, - "httpcode" => 200 + "httpcode" => $statusCode ]; $apiclient->method("call_persistence")->willReturn($mockResponse); - $persistence = new PostgresPersistence($apiclient); - $response = $persistence->getContext($vis_id); - $this->assertIsArray($response); + return $apiclient; } } \ No newline at end of file From 86f14a3d30c328e590c9ba65e00e7e16de7abe56 Mon Sep 17 00:00:00 2001 From: chreman Date: Fri, 10 Jan 2025 22:28:43 +0100 Subject: [PATCH 14/20] PHP test updates; getContext refactoring --- server/classes/headstart/composer.lock | 12 +++---- .../library/getContextResultBuilder.php | 35 +++++++++---------- .../persistence/DispatchingPersistence.php | 1 + .../persistence/PostgresPersistence.php | 10 ++++++ server/classes/headstart/phpunit.xml | 9 +++-- .../tests/PostgresPersistenceTest.php | 19 ++++++++++ server/services/getContext.php | 10 +++--- 7 files changed, 66 insertions(+), 30 deletions(-) diff --git a/server/classes/headstart/composer.lock b/server/classes/headstart/composer.lock index 407da8237..4569d5fb4 100644 --- a/server/classes/headstart/composer.lock +++ b/server/classes/headstart/composer.lock @@ -69,16 +69,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.3.1", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", - "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", "shasum": "" }, "require": { @@ -121,9 +121,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" }, - "time": "2024-10-08T18:51:32+00:00" + "time": "2024-12-30T11:07:19+00:00" }, { "name": "phar-io/manifest", diff --git a/server/classes/headstart/library/getContextResultBuilder.php b/server/classes/headstart/library/getContextResultBuilder.php index c1c1d88e9..acbce6982 100644 --- a/server/classes/headstart/library/getContextResultBuilder.php +++ b/server/classes/headstart/library/getContextResultBuilder.php @@ -1,6 +1,7 @@ persistence = $persistence; - } - - public function getContext($vis_id) { - // TODO: remove the [0] unpacking from array - $data = $this->persistence->getContext($vis_id)[0]; - $return_data = array("id" => $data["rev_vis"], - "query" => $data["vis_query"], - "service" => $data["vis_title"], - "timestamp" => $data["rev_timestamp"], - "params" => $data["vis_params"]); - if (array_key_exists("additional_context", $data)) { - $return_data = array_merge($return_data, $data["additional_context"]); + public function getContext(VisualizationContext $visualizationContext): string { + // if data result is not success, return error reason array + $httpcode = $visualizationContext->httpcode; + $data = $visualizationContext->data; + if ($httpcode === 200) { + $return_data = array("id" => $data["rev_vis"], + "query" => $data["vis_query"], + "service" => $data["vis_title"], + "timestamp" => $data["rev_timestamp"], + "params" => $data["vis_params"]); + if (array_key_exists("additional_context", $data)) { + $return_data = array_merge($return_data, $data["additional_context"]); + } + } else { + $return_data = $data; } $result = json_encode($return_data); return $result; } - } \ No newline at end of file diff --git a/server/classes/headstart/persistence/DispatchingPersistence.php b/server/classes/headstart/persistence/DispatchingPersistence.php index 5b5b47927..29af73e75 100644 --- a/server/classes/headstart/persistence/DispatchingPersistence.php +++ b/server/classes/headstart/persistence/DispatchingPersistence.php @@ -4,6 +4,7 @@ /** * This class implements the PersistenceInterface and provides methods to interact with the database. + * Deprecated, this should now be removed. */ class DispatchingPersistence implements Persistence { diff --git a/server/classes/headstart/persistence/PostgresPersistence.php b/server/classes/headstart/persistence/PostgresPersistence.php index 7bd67438c..c6d84258b 100644 --- a/server/classes/headstart/persistence/PostgresPersistence.php +++ b/server/classes/headstart/persistence/PostgresPersistence.php @@ -4,6 +4,7 @@ use headstart\library\APIClient; require_once 'Persistence.php'; +require_once 'VisualizationContext.php'; /** * This class implements the PersistenceInterface and provides methods to interact with the database. @@ -98,6 +99,15 @@ public function getContext($vis_id): array|bool return array($data); } + public function getVisualizationContext($vis_id): VisualizationContext + { + $payload = json_encode(array("vis_id" => $vis_id)); + $res = $this->api_client->call_persistence("getContext", $payload); + $data = json_decode($res["result"], true); + $httpcode = $res["httpcode"]; + return new VisualizationContext($data, $httpcode); + } + public function createID($string_array, $payload): string { $res = $this->api_client->call_persistence("createID", $payload); diff --git a/server/classes/headstart/phpunit.xml b/server/classes/headstart/phpunit.xml index d33ec4e22..71abfb957 100644 --- a/server/classes/headstart/phpunit.xml +++ b/server/classes/headstart/phpunit.xml @@ -1,5 +1,10 @@ - + @@ -10,5 +15,5 @@ src - + diff --git a/server/classes/headstart/tests/PostgresPersistenceTest.php b/server/classes/headstart/tests/PostgresPersistenceTest.php index 485c1b8e0..7834bcc66 100644 --- a/server/classes/headstart/tests/PostgresPersistenceTest.php +++ b/server/classes/headstart/tests/PostgresPersistenceTest.php @@ -9,6 +9,7 @@ use headstart\persistence\PostgresPersistence; use headstart\library\APIClient; use PHPUnit\Framework\TestCase; +use headstart\persistence\VisualizationContext; /** * @covers \headstart\persistence\PostgresPersistence @@ -42,6 +43,24 @@ public function testWhenVisIDNotInDBReturnsAResponseObjectWeCanHandle(): void { $this->assertIsArray($response); } + public function testThatInSuccesfulConditionsReturnsAVisualizationContextWeCanHandle(): void { + $apiclient = $this->getMockedApiclient("successfulGetContextResponse.json", 200); + $persistence = new PostgresPersistence($apiclient); + $vis_id = "asdfasdf"; + $response = $persistence->getVisualizationContext($vis_id); + + $this->assertInstanceOf(VisualizationContext::class, $response); + } + + public function testWhenDBMissingReturnsAVisualizationContextWeCanHandle(): void { + $apiclient = $this->getMockedApiclient("unsuccessfulGetContextDBHostCannotBeResolved.json", 503); + $persistence = new PostgresPersistence($apiclient); + $vis_id = "asdfasdf"; + $response = $persistence->getVisualizationContext($vis_id); + + $this->assertInstanceOf(VisualizationContext::class, $response); + } + private function getMockedApiclient(string $jsonFileName, int $statusCode): Apiclient { $apiclient = $this->createMock(APIClient::class); $jsonFilePath = __DIR__ . "/test_data/" . $jsonFileName; diff --git a/server/services/getContext.php b/server/services/getContext.php index ab14720e0..34e49ea07 100644 --- a/server/services/getContext.php +++ b/server/services/getContext.php @@ -24,16 +24,18 @@ // Remove the calls to this getContext on the persistence object. Replace instead with a getContextResultBuilder that returns a result object // This should contain the httpStatusCode to pass to the client, the result in string form (some json encoded string) and it should never throw. -$getContextResultBuilder = new \headstart\library\getContextResultBuilder($persistence); +$getContextResultBuilder = new \headstart\library\getContextResultBuilder(); // [thing that formats the response for the user] - [thing that parses responses from the persistence api] - [thing that makes requests to persisent api and handles the network calls etc.] // Err... why is the only caller of this having to unpack the array to take the first result? Is someone wrapping this reponse in an array unecessarily? // $data = $persistence->getContext($vis_id)[0]; -$result = $getContextResultBuilder->getContext($vis_id); +// $result = $getContextResultBuilder->getContext($vis_id); +$visualizationContext = $persistence->getVisualizationContext($vis_id); +http_response_code($visualizationContext->httpcode); /* -It it works +If it works { "rev_timestamp": "Thu, 12 Sep 2024 10:23:47 GMT", "rev_vis": "d161dba364a1e8c0468b9c74407e3575", @@ -54,4 +56,4 @@ // To investigate: is anyone needing the callback version of this?? // meaning, can this be simplified to just echo $result; // library\CommUtils::echoOrCallback($result, $_GET); -echo $result; +echo $getContextResultBuilder->getContext($visualizationContext); \ No newline at end of file From 3b5e9d0aea0ae43dda5818042cb29bf3980418d1 Mon Sep 17 00:00:00 2001 From: chreman Date: Fri, 17 Jan 2025 22:29:56 +0100 Subject: [PATCH 15/20] requirements updates --- server/workers/persistence/Dockerfile | 1 - server/workers/persistence/requirements.txt | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/workers/persistence/Dockerfile b/server/workers/persistence/Dockerfile index f682ba27b..4401c95e7 100644 --- a/server/workers/persistence/Dockerfile +++ b/server/workers/persistence/Dockerfile @@ -8,5 +8,4 @@ WORKDIR /persistence COPY workers/persistence/requirements.txt . RUN pip install --upgrade pip RUN pip install --no-cache-dir -r requirements.txt -RUN pip install git+https://github.com/python-restx/flask-restx COPY workers/persistence/src/ ./ \ No newline at end of file diff --git a/server/workers/persistence/requirements.txt b/server/workers/persistence/requirements.txt index 6eab26c89..e8f5c630e 100644 --- a/server/workers/persistence/requirements.txt +++ b/server/workers/persistence/requirements.txt @@ -17,4 +17,5 @@ SQLAlchemy==2.0.23 SQLAlchemy-Utils==0.41.1 typing_extensions==4.7.1 Werkzeug==3.0.1 -zipp==3.15.0 \ No newline at end of file +zipp==3.15.0 +flask-restx==1.3.0 \ No newline at end of file From 65a550da923d06881201ad88e8729e9399545569 Mon Sep 17 00:00:00 2001 From: chreman Date: Tue, 21 Jan 2025 23:45:03 +0100 Subject: [PATCH 16/20] add missing file --- .../persistence/VisualizationContext.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 server/classes/headstart/persistence/VisualizationContext.php diff --git a/server/classes/headstart/persistence/VisualizationContext.php b/server/classes/headstart/persistence/VisualizationContext.php new file mode 100644 index 000000000..28dc4c91c --- /dev/null +++ b/server/classes/headstart/persistence/VisualizationContext.php @@ -0,0 +1,19 @@ +data = $data; + $this->httpcode = $httpcode; + } + +} \ No newline at end of file From 13ef35fa9e80b4e4a625a5d013f904f019156497 Mon Sep 17 00:00:00 2001 From: chreman Date: Tue, 28 Jan 2025 22:03:30 +0100 Subject: [PATCH 17/20] bugfix for metadata processing --- server/workers/base/src/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/workers/base/src/base.py b/server/workers/base/src/base.py index d08b8f31d..ed0c9bf1b 100644 --- a/server/workers/base/src/base.py +++ b/server/workers/base/src/base.py @@ -234,7 +234,7 @@ def mark_duplicate_links(df): def identify_relations(df): for udoi in df.unversioned_doi.unique(): if udoi: - tmp = df[df.identifier.str.contains(udoi)] + tmp = df[df.identifier.str.contains(udoi, regex=False)] if len(tmp) > 1: relations = tmp.id r = pd.Series([relations.values.tolist()]*len(tmp), index=relations.index) From a9e9907e1cc54cd14af9c6e85c546f796a8ecf12 Mon Sep 17 00:00:00 2001 From: chreman Date: Tue, 28 Jan 2025 22:05:11 +0100 Subject: [PATCH 18/20] bugfix for parameter processing --- server/workers/api/src/apis/pubmed.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/server/workers/api/src/apis/pubmed.py b/server/workers/api/src/apis/pubmed.py index 2f85a77d7..498f75b9b 100644 --- a/server/workers/api/src/apis/pubmed.py +++ b/server/workers/api/src/apis/pubmed.py @@ -53,6 +53,7 @@ def post(self): if "optradio" in params: del params["optradio"] errors = search_param_schema.validate(params, partial=True) + params = sanitize_params(params) params["limit"] = 100 params["list_size"] = 100 pubmed_ns.logger.debug(errors) @@ -91,4 +92,11 @@ def post(self): class ServiceVersion(Resource): def get(self): result = {"service_version": os.getenv("SERVICE_VERSION")} - return make_response(result, 200, {"Content-Type": "application/json"}) \ No newline at end of file + return make_response(result, 200, {"Content-Type": "application/json"}) + +def sanitize_params(params): + article_types = params.get("article_types") + if article_types: + [at.replace("\'", "'") for at in article_types] + return params + \ No newline at end of file From 9713bd80507877075f3c9954afe26a28040d3435 Mon Sep 17 00:00:00 2001 From: chreman Date: Tue, 28 Jan 2025 22:06:09 +0100 Subject: [PATCH 19/20] bugfix for parameter processing --- server/workers/api/src/apis/pubmed.py | 1 + 1 file changed, 1 insertion(+) diff --git a/server/workers/api/src/apis/pubmed.py b/server/workers/api/src/apis/pubmed.py index 498f75b9b..dd2c76bd5 100644 --- a/server/workers/api/src/apis/pubmed.py +++ b/server/workers/api/src/apis/pubmed.py @@ -98,5 +98,6 @@ def sanitize_params(params): article_types = params.get("article_types") if article_types: [at.replace("\'", "'") for at in article_types] + params["article_types"] = article_types return params \ No newline at end of file From 240cf7c4239d257d3bb1355ef725c61bd0b3c297 Mon Sep 17 00:00:00 2001 From: chreman Date: Wed, 29 Jan 2025 00:22:27 +0100 Subject: [PATCH 20/20] pubmed query bugfix --- server/workers/api/src/apis/pubmed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/workers/api/src/apis/pubmed.py b/server/workers/api/src/apis/pubmed.py index dd2c76bd5..ba56ed14f 100644 --- a/server/workers/api/src/apis/pubmed.py +++ b/server/workers/api/src/apis/pubmed.py @@ -97,7 +97,7 @@ def get(self): def sanitize_params(params): article_types = params.get("article_types") if article_types: - [at.replace("\'", "'") for at in article_types] + article_types = [at.replace("'", "'") for at in article_types] params["article_types"] = article_types return params \ No newline at end of file