From 18db63573186a24df3313b0d84d055730e4d6b9b Mon Sep 17 00:00:00 2001 From: Jonathan Boivin Date: Sun, 1 Dec 2024 13:10:27 -0500 Subject: [PATCH 1/8] Add method to remove the alternate description if not modified but the main is. Signed-off-by: Jonathan Boivin --- lib/CalDAV/Schedule/Plugin.php | 44 ++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/lib/CalDAV/Schedule/Plugin.php b/lib/CalDAV/Schedule/Plugin.php index 8577ae9f70..3092b3628f 100644 --- a/lib/CalDAV/Schedule/Plugin.php +++ b/lib/CalDAV/Schedule/Plugin.php @@ -597,8 +597,9 @@ public function getSupportedPrivilegeSet(INode $node, array &$supportedPrivilege } /** - * This method looks at an old iCalendar object, a new iCalendar object and - * starts sending scheduling messages based on the changes. + * This method looks at an old iCalendar object, a new iCalendar object and: + * - starts sending scheduling messages based on the changes. + * - ensures the description fields are coherent * * A list of addresses needs to be specified, so the system knows who made * the update, because the behavior may be different based on if it's an @@ -612,6 +613,8 @@ public function getSupportedPrivilegeSet(INode $node, array &$supportedPrivilege */ protected function processICalendarChange($oldObject, VCalendar $newObject, array $addresses, array $ignore = [], &$modified = false) { + $this->ensureDescriptionConsistency($oldObject, $newObject, $modified); + $broker = $this->createITipBroker(); $messages = $broker->parseEvent($newObject, $addresses, $oldObject); @@ -1003,4 +1006,41 @@ protected function createITipBroker(): Broker { return new Broker(); } + + /** + * Ensure the alternate version of the description is removed if only the main one is changed + */ + private function ensureDescriptionConsistency($oldObj, VCalendar $vCal, &$modified) { + if (!$oldObj) { + return; // No previous version to compare + } + + $xAltDescPropName = "X-ALT-DESC"; + + // Get presence of description fields + $hasOldDescription = isset($oldObj->VTODO) && isset($oldObj->VTODO->DESCRIPTION); + $hasNewDescription = isset($vCal->VTODO) && isset($vCal->VTODO->DESCRIPTION); + $hasOldXAltDesc = isset($oldObj->VTODO) && isset($oldObj->VTODO->{$xAltDescPropName}); + $hasNewXAltDesc = isset($vCal->VTODO) && isset($vCal->VTODO->{$xAltDescPropName}); + $hasAllDesc = $hasOldDescription && $hasNewDescription && $hasOldXAltDesc && $hasNewXAltDesc; + + // If all description fields are present, then verify consistency + if ($hasAllDesc) { + // Get descriptions + $oldDescription = (string) $oldObj->VTODO->DESCRIPTION; + $newDescription = (string) $vCal->VTODO->DESCRIPTION; + $oldXAltDesc = (string) $oldObj->VTODO->{$xAltDescPropName}; + $newXAltDesc = (string) $vCal->VTODO->{$xAltDescPropName}; + + // Compare descriptions + $isSameDescription = $oldDescription === $newDescription; + $isSameXAltDesc = $oldXAltDesc === $newXAltDesc; + + // If the description changed, but not the alternate one, then delete the latest + if (!$isSameDescription && $isSameXAltDesc) { + unset($vCal->VTODO->{$xAltDescPropName}); + $modified = true; + } + } + } } From a232dddab6d61afa0f36f943db5186e07ef1341f Mon Sep 17 00:00:00 2001 From: Jonathan Boivin Date: Wed, 11 Dec 2024 23:55:10 -0500 Subject: [PATCH 2/8] Add docker support for unit tests --- tests/docker/Dockerfile | 24 ++++++++++++++++++++++ tests/docker/README.md | 9 +++++++++ tests/docker/docker-compose.yml | 8 ++++++++ tests/docker/php.sources | 34 +++++++++++++++++++++++++++++++ tests/docker/run-tests.sh | 36 +++++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+) create mode 100644 tests/docker/Dockerfile create mode 100644 tests/docker/README.md create mode 100644 tests/docker/docker-compose.yml create mode 100644 tests/docker/php.sources create mode 100644 tests/docker/run-tests.sh diff --git a/tests/docker/Dockerfile b/tests/docker/Dockerfile new file mode 100644 index 0000000000..f3119c4848 --- /dev/null +++ b/tests/docker/Dockerfile @@ -0,0 +1,24 @@ +FROM ubuntu:24.04 + +# Install PHP +RUN apt update -y +RUN apt install ca-certificates -y +ADD php.sources /etc/apt/sources.list.d/ +RUN apt update -y +RUN apt install -y php7.4 php7.4-xml php7.4-mbstring php7.4-curl php7.4-sqlite3 +RUN apt install -y curl zip git + +# Install composer +RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" +RUN php composer-setup.php --version=2.8.3 +RUN mv composer.phar /usr/local/bin/composer +RUN rm composer-setup.php + +# Setup tests +RUN mkdir /src/ +ADD run-tests.sh . +RUN chmod +x run-tests.sh + +ENTRYPOINT ["/run-tests.sh"] + +# docker run -ti -v /mnt/d/temp/repos/sabre-dav:/src:rw sabre-dav-unit-tests:latest /bin/bash \ No newline at end of file diff --git a/tests/docker/README.md b/tests/docker/README.md new file mode 100644 index 0000000000..929531c365 --- /dev/null +++ b/tests/docker/README.md @@ -0,0 +1,9 @@ +USAGE +===== + +- Install Docker +- Download the folder **/tests/docker** from the repository +- Goto that folder using a terminal +- Run `docker compose up` +- Run `docker run -ti sabre-dav-unit-tests` + diff --git a/tests/docker/docker-compose.yml b/tests/docker/docker-compose.yml new file mode 100644 index 0000000000..ee897fa530 --- /dev/null +++ b/tests/docker/docker-compose.yml @@ -0,0 +1,8 @@ +services: + sabre-dav-unit-tests: + entrypoint: bash -c "echo Execute docker run -ti sabre-dav-unit-tests to start" + container_name: sabre-dav-unit-tests + build: + context: ./ + dockerfile: ./Dockerfile + image: sabre-dav-unit-tests:latest \ No newline at end of file diff --git a/tests/docker/php.sources b/tests/docker/php.sources new file mode 100644 index 0000000000..0913c78b91 --- /dev/null +++ b/tests/docker/php.sources @@ -0,0 +1,34 @@ +Types: deb +URIs: https://ppa.launchpadcontent.net/ondrej/php/ubuntu/ +Suites: noble +Components: main +Signed-By: + -----BEGIN PGP PUBLIC KEY BLOCK----- + . + mQINBGYo0vEBEAC0Semxy5I2b8exRUxJfTKkHR4f5uyS0dTd9vYgMI5T3gsa7ypH + HtE+GiZC+T9m/F9h66+XJMxhuNsKRs7T2In5NSeso9H/ytlSTayUaBtCFfRp6y6b + 6ozuRBfqYJGxhjAnIzvNF/Wpp2BvfQm3OrQ7uJJrt5IvzLDC4jPxl/Xs3sTT+Hbk + bkKKprZ3xmy2enuwBaNWR/CUtAz3hbkzL1kGbhX9m3QidFJagVVdDw3aNEwo8ush + djWfF+BajNvpDFYJKBGQbCeagB753Baa5yIN62x+THLnLiKTMDS1e7U0ZDiV9671 + noTbtN5TeZeyfsEmeZ8X60x11JIP3yYHYZT70/DyTYX3WC9yQFyIgVOfRlGklMKI + k3TLMmtq8w5Hz1vovwzV7PzaQnmY+uNP2ZbAP4fJ3iFAj0L+u0i1nOFgTy0Lq058 + O/FjRrQxuceDDCF+9ThspXMw3Puvz8giuBDCdEda84uC7XWMdqgz/maLfFQjAmyP + Ixi1EMxMlHYyZajpR1cdCfrAIQlnQjHSWmyeCFgXPPfRA71aCcJ7oSrDjogW6Ahd + HRkQRKf1FF9BFzycgSQotfR+7CKfPQh1kghufM9W/spARzA709nGZjXJzgEJLQd3 + CDB6dIIxT/0YI36h3Qgfmiiw4twO24MMEqEEPIELz2WJKeWGkdQdcekpxQARAQAB + tB9MYXVuY2hwYWQgUFBBIGZvciBPbmTFmWVqIFN1csO9iQJOBBMBCgA4FiEEuNx+ + U5RmVu+85MHdcdrqq0rUyrYFAmYo0vECGwMFCwkIBwIGFQoJCAsCBBYCAwECHgEC + F4AACgkQcdrqq0rUyrYOPQ/+IArA4s1J3op/w7cXek0ieFHWHFDrxPYS+78/LF/J + LoYZw0nIU5Ovr+LzehFMIQU6esgPXwbeCVgwLwat57augAkAYWT0UzH5dE6RKAGr + C2vsHWVfPhQn6UndfzwXc0mTLGQni25aQaZ6k60Dbm/vblejrTQrtAUWoMO3Z1cr + NDGJ3Z9DCxtr2o9gRYUI6HwLHJtobTIeI5xsr5x+GvXiIAVCPa3ZEuRL6jMQfqfS + C43mpuiS1kGgsnQLs2DbN7EFCfiJoNX1QzZu25zg+IS9PXbCJnheZWnH0rwUSb/N + hZPcSefGlNlhr824OfT30v79hQnw59XbsfV270O9jPbD4kttN+OiszbU66zsuiOh + BO46XCckQPqDkBMw56GPFuVrQgGb1thXvn67URJgPyJhwauBWKPNAJ9Ojuo+yVq/ + hdR1VNWThXQbZgaGSWrbjt6FdYtQb9VX88uu5gFDmr180HogHNUDUcqNLLdnjfFs + 4DyJlusQ5I/a7cQ7nlkNgxAmHszwO/mGLBuGljDUYkwZDW9nqP1Q5Q2jMtrhgXvR + 2SOtufvecUbB7+eoRSaOnu7CNMATG6LocFEMzhKUde1uZTfWSqnYEcdqoFJMi46y + qaNxhiNLsQ5OBMbgSp2zCbQxRBdITMVvBR5YjCetUIGEs6T1yQ5wh5Xpoi34ShHn + v38= + =kFlZ + -----END PGP PUBLIC KEY BLOCK----- \ No newline at end of file diff --git a/tests/docker/run-tests.sh b/tests/docker/run-tests.sh new file mode 100644 index 0000000000..d1fb0b320e --- /dev/null +++ b/tests/docker/run-tests.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +repoUrl= +while [ -z "$repoUrl" ] +do + read -p "Please enter public repository URL:" repoUrl + + if [ -z "$repoUrl" ]; then echo "Repository URL is mandatory"; fi +done + +read -p "Enter the branch name [default: master]" branchName +branchName=${branchName:-master} + +echo "Are you sure you want to test with?" +echo "URL: $repoUrl" +echo "Branch: $branchName" +read -p "[y/N]" confirm + +if [ "$confirm" != "Y" ] && [ "$confirm" != "y" ]; then + echo "Cancelling test run" + exit +fi + +echo "Starting setup" + +git clone -b "$branchName" --single-branch --depth 1 "$repoUrl" /src/ + +( + cd /src/ + composer install + + mkdir -p vendor/sabre/http/tests/www + php -S localhost:8000 -t vendor/sabre/http/tests/www & + + composer phpunit +) From a8a1dceac0dc6f701b04e9aa7f9510fe96758c5d Mon Sep 17 00:00:00 2001 From: Jonathan Boivin Date: Thu, 12 Dec 2024 00:16:35 -0500 Subject: [PATCH 3/8] Remove debugging commented line --- tests/docker/Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/docker/Dockerfile b/tests/docker/Dockerfile index f3119c4848..f26fd74cbe 100644 --- a/tests/docker/Dockerfile +++ b/tests/docker/Dockerfile @@ -20,5 +20,3 @@ ADD run-tests.sh . RUN chmod +x run-tests.sh ENTRYPOINT ["/run-tests.sh"] - -# docker run -ti -v /mnt/d/temp/repos/sabre-dav:/src:rw sabre-dav-unit-tests:latest /bin/bash \ No newline at end of file From d789d4fad37cdb8b9d2c291892aa3b14b82a6607 Mon Sep 17 00:00:00 2001 From: Jonathan Boivin Date: Sat, 1 Mar 2025 19:01:21 -0500 Subject: [PATCH 4/8] Executed composer cs-fixer Signed-off-by: Jonathan Boivin --- lib/CalDAV/Schedule/Plugin.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/CalDAV/Schedule/Plugin.php b/lib/CalDAV/Schedule/Plugin.php index 3092b3628f..55b1fa7908 100644 --- a/lib/CalDAV/Schedule/Plugin.php +++ b/lib/CalDAV/Schedule/Plugin.php @@ -599,7 +599,7 @@ public function getSupportedPrivilegeSet(INode $node, array &$supportedPrivilege /** * This method looks at an old iCalendar object, a new iCalendar object and: * - starts sending scheduling messages based on the changes. - * - ensures the description fields are coherent + * - ensures the description fields are coherent. * * A list of addresses needs to be specified, so the system knows who made * the update, because the behavior may be different based on if it's an @@ -614,7 +614,7 @@ public function getSupportedPrivilegeSet(INode $node, array &$supportedPrivilege protected function processICalendarChange($oldObject, VCalendar $newObject, array $addresses, array $ignore = [], &$modified = false) { $this->ensureDescriptionConsistency($oldObject, $newObject, $modified); - + $broker = $this->createITipBroker(); $messages = $broker->parseEvent($newObject, $addresses, $oldObject); @@ -1006,16 +1006,17 @@ protected function createITipBroker(): Broker { return new Broker(); } - + /** - * Ensure the alternate version of the description is removed if only the main one is changed + * Ensure the alternate version of the description is removed if only the main one is changed. */ - private function ensureDescriptionConsistency($oldObj, VCalendar $vCal, &$modified) { + private function ensureDescriptionConsistency($oldObj, VCalendar $vCal, &$modified) + { if (!$oldObj) { return; // No previous version to compare } - $xAltDescPropName = "X-ALT-DESC"; + $xAltDescPropName = 'X-ALT-DESC'; // Get presence of description fields $hasOldDescription = isset($oldObj->VTODO) && isset($oldObj->VTODO->DESCRIPTION); From f877dc96ec5fbdbbb8e2d40c7adcf3d6413ce872 Mon Sep 17 00:00:00 2001 From: Jonathan Boivin Date: Sat, 1 Mar 2025 20:18:18 -0500 Subject: [PATCH 5/8] Add param description + rename parameter to be consistent Signed-off-by: Jonathan Boivin --- lib/CalDAV/Schedule/Plugin.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/CalDAV/Schedule/Plugin.php b/lib/CalDAV/Schedule/Plugin.php index 55b1fa7908..392157da99 100644 --- a/lib/CalDAV/Schedule/Plugin.php +++ b/lib/CalDAV/Schedule/Plugin.php @@ -1009,28 +1009,32 @@ protected function createITipBroker(): Broker /** * Ensure the alternate version of the description is removed if only the main one is changed. + * + * @param VCalendar|string|null $oldObject + * @param \Sabre\VObject\Component\VCalendar $vCal + * @param bool $modified a marker to indicate that the original object modified by this process */ - private function ensureDescriptionConsistency($oldObj, VCalendar $vCal, &$modified) + private function ensureDescriptionConsistency($oldObject, VCalendar $vCal, &$modified) { - if (!$oldObj) { + if (!$oldObject) { return; // No previous version to compare } $xAltDescPropName = 'X-ALT-DESC'; // Get presence of description fields - $hasOldDescription = isset($oldObj->VTODO) && isset($oldObj->VTODO->DESCRIPTION); + $hasOldDescription = isset($oldObject->VTODO) && isset($oldObject->VTODO->DESCRIPTION); $hasNewDescription = isset($vCal->VTODO) && isset($vCal->VTODO->DESCRIPTION); - $hasOldXAltDesc = isset($oldObj->VTODO) && isset($oldObj->VTODO->{$xAltDescPropName}); + $hasOldXAltDesc = isset($oldObject->VTODO) && isset($oldObject->VTODO->{$xAltDescPropName}); $hasNewXAltDesc = isset($vCal->VTODO) && isset($vCal->VTODO->{$xAltDescPropName}); $hasAllDesc = $hasOldDescription && $hasNewDescription && $hasOldXAltDesc && $hasNewXAltDesc; // If all description fields are present, then verify consistency if ($hasAllDesc) { // Get descriptions - $oldDescription = (string) $oldObj->VTODO->DESCRIPTION; + $oldDescription = (string) $oldObject->VTODO->DESCRIPTION; $newDescription = (string) $vCal->VTODO->DESCRIPTION; - $oldXAltDesc = (string) $oldObj->VTODO->{$xAltDescPropName}; + $oldXAltDesc = (string) $oldObject->VTODO->{$xAltDescPropName}; $newXAltDesc = (string) $vCal->VTODO->{$xAltDescPropName}; // Compare descriptions From 7ab12d429732920282b9006fe2429a68f0437317 Mon Sep 17 00:00:00 2001 From: Jonathan Boivin Date: Sat, 1 Mar 2025 21:22:08 -0500 Subject: [PATCH 6/8] Add running local repository option Signed-off-by: Jonathan Boivin --- tests/docker/README.md | 18 ++++++++- tests/docker/run-tests.sh | 78 ++++++++++++++++++++++++--------------- 2 files changed, 66 insertions(+), 30 deletions(-) diff --git a/tests/docker/README.md b/tests/docker/README.md index 929531c365..1e5abfcc46 100644 --- a/tests/docker/README.md +++ b/tests/docker/README.md @@ -2,8 +2,24 @@ USAGE ===== - Install Docker + +REPO +---- + - Download the folder **/tests/docker** from the repository - Goto that folder using a terminal - Run `docker compose up` -- Run `docker run -ti sabre-dav-unit-tests` +- Run `docker run --rm -ti sabre-dav-unit-tests` + +LOCAL +----- + +- Goto **$local_repo_path/tests/docker** using a terminal +- Run `docker compose up` +- Run `docker run --rm -ti -v $local_repo_path:/test-dir/ sabre-dav-unit-tests` + +DEV +--- +- Apply changes to Dockerfile +- Run `docker compose up --build` \ No newline at end of file diff --git a/tests/docker/run-tests.sh b/tests/docker/run-tests.sh index d1fb0b320e..bbd4c9de0c 100644 --- a/tests/docker/run-tests.sh +++ b/tests/docker/run-tests.sh @@ -1,36 +1,56 @@ #!/bin/bash -repoUrl= -while [ -z "$repoUrl" ] -do - read -p "Please enter public repository URL:" repoUrl - - if [ -z "$repoUrl" ]; then echo "Repository URL is mandatory"; fi -done +function executeTests() +# $1 = Source directory +{ + src="$1" + ( + cd "$src" + composer install + + mkdir -p vendor/sabre/http/tests/www + php -S localhost:8000 -t vendor/sabre/http/tests/www & + + composer phpunit + ) +} -read -p "Enter the branch name [default: master]" branchName -branchName=${branchName:-master} +function downloadRepo() +{ + local repoUrl= + while [ -z "$repoUrl" ] + do + read -p "Please enter public repository URL:" repoUrl + + if [ -z "$repoUrl" ]; then echo "Repository URL is mandatory"; fi + done + + local branchName= + read -p "Enter the branch name [default: master]" branchName + branchName=${branchName:-master} + + echo "Are you sure you want to test with?" + echo "URL: $repoUrl" + echo "Branch: $branchName" + read -p "[y/N]" confirm + + if [ "$confirm" != "Y" ] && [ "$confirm" != "y" ]; then + echo "Cancelling test run" + exit + fi + + git clone -b "$branchName" --single-branch --depth 1 "$repoUrl" /src/ +} -echo "Are you sure you want to test with?" -echo "URL: $repoUrl" -echo "Branch: $branchName" -read -p "[y/N]" confirm +echo "Starting test container" -if [ "$confirm" != "Y" ] && [ "$confirm" != "y" ]; then - echo "Cancelling test run" - exit +src=/test-dir/ +if [ -d $src ]; then + echo "Using local volume" +else + src=/src/ + echo "Using repository" + downloadRepo fi -echo "Starting setup" - -git clone -b "$branchName" --single-branch --depth 1 "$repoUrl" /src/ - -( - cd /src/ - composer install - - mkdir -p vendor/sabre/http/tests/www - php -S localhost:8000 -t vendor/sabre/http/tests/www & - - composer phpunit -) +executeTests "$src" From 430021db7b60458dd7a3e54d5488782ac328924b Mon Sep 17 00:00:00 2001 From: Jonathan Boivin Date: Sat, 1 Mar 2025 21:31:47 -0500 Subject: [PATCH 7/8] Remove git warning Signed-off-by: Jonathan Boivin --- tests/docker/run-tests.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/docker/run-tests.sh b/tests/docker/run-tests.sh index bbd4c9de0c..c17c072f9d 100644 --- a/tests/docker/run-tests.sh +++ b/tests/docker/run-tests.sh @@ -46,7 +46,8 @@ echo "Starting test container" src=/test-dir/ if [ -d $src ]; then - echo "Using local volume" + echo "Using local volume" + git config --global --add safe.directory /test-dir else src=/src/ echo "Using repository" From 0c283f833ea7ba95721d5eb434ca95db6f2a5921 Mon Sep 17 00:00:00 2001 From: Jonathan Boivin Date: Sat, 1 Mar 2025 21:41:15 -0500 Subject: [PATCH 8/8] Create local execution script Signed-off-by: Jonathan Boivin --- tests/docker/README.md | 5 ++++- tests/docker/run-local.sh | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 tests/docker/run-local.sh diff --git a/tests/docker/README.md b/tests/docker/README.md index 1e5abfcc46..5481dc0408 100644 --- a/tests/docker/README.md +++ b/tests/docker/README.md @@ -16,7 +16,10 @@ LOCAL - Goto **$local_repo_path/tests/docker** using a terminal - Run `docker compose up` -- Run `docker run --rm -ti -v $local_repo_path:/test-dir/ sabre-dav-unit-tests` +- Run either: + - `docker run --rm -ti -v $local_repo_path:/test-dir/ sabre-dav-unit-tests` + - `./run-local.sh` + DEV --- diff --git a/tests/docker/run-local.sh b/tests/docker/run-local.sh new file mode 100644 index 0000000000..fa62c020ab --- /dev/null +++ b/tests/docker/run-local.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run -ti --rm -v $(realpath "$(dirname $0)/../../"):/test-dir/ sabre-dav-unit-tests