Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions .github/workflows/phpunit-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# SPDX-FileCopyrightText: 2026 Nextcloud contributors
# SPDX-License-Identifier: AGPL-3.0-or-later

name: PHPUnit Coverage

on:
push:
branches:
- master
- main
workflow_dispatch:

permissions:
contents: read

concurrency:
group: phpunit-coverage-${{ github.ref }}
cancel-in-progress: true

jobs:
matrix:
runs-on: ubuntu-latest-low
outputs:
php-version: ${{ steps.versions.outputs.php-max }}
server-version: ${{ steps.versions.outputs.branches-max }}
steps:
- name: Checkout app
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Get version matrix
id: versions
uses: icewind1991/nextcloud-version-matrix@8a7bac6300b2f0f3100088b297995a229558ddba # v1.3.2.3.1.3.2

coverage:
runs-on: ubuntu-latest

needs: [matrix]

name: Coverage PHP ${{ needs.matrix.outputs.php-version }} Nextcloud ${{ needs.matrix.outputs.server-version }}

steps:
- name: Set app env
if: ${{ env.APP_NAME == '' }}
run: |
# Split and keep last
echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV

- name: Checkout server
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
submodules: true
repository: nextcloud/server
ref: ${{ needs.matrix.outputs.server-version }}

- name: Checkout app
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
path: apps/${{ env.APP_NAME }}

- name: Set up php ${{ needs.matrix.outputs.php-version }}
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.36.0
with:
php-version: ${{ needs.matrix.outputs.php-version }}
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
coverage: pcov
ini-file: development
ini-values: disable_functions=
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Set up dependencies
working-directory: apps/${{ env.APP_NAME }}
run: |
composer remove nextcloud/ocp --dev
composer i

- name: Set up Nextcloud
run: |
mkdir data
./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-host=127.0.0.1 --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
./occ app:enable --force ${{ env.APP_NAME }}

- name: PHPUnit with coverage
working-directory: apps/${{ env.APP_NAME }}
run: composer run test:unit -- --coverage-clover coverage.xml --coverage-text --colors=never 2>&1 | tee /tmp/coverage.txt

- name: Write coverage summary
run: |
echo '## Test Coverage' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
grep -A 999 'Code Coverage Report' /tmp/coverage.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY

- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: apps/${{ env.APP_NAME }}/coverage.xml
retention-days: 7

- name: Print logs
if: always()
run: |
cat data/nextcloud.log
35 changes: 34 additions & 1 deletion lib/Db/Poll.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class Poll extends EntityWithUser implements JsonSerializable {
protected int $adminAccess = 0;
protected int $allowComment = 0;
protected int $hideBookedUp = 0;
protected int $useNo = 0;
protected int $useNo = 1;
protected int $lastInteraction = 0;
protected ?string $miscSettings = '';
protected string $votingVariant = '';
Expand Down Expand Up @@ -220,6 +220,39 @@ public function __clone() {
$this->setAnonymous(0);
}

/**
* Build a fresh Poll entity pre-populated from this poll's settings.
* The fresh entity's id is never set, so QBMapper::insert() relies on the
* DB autoincrement to assign a fresh id.
*/
public function createClone(string $newOwner): self {
$clone = new self();
$clone->setType($this->getType());
$clone->setVotingVariant($this->getVotingVariant());
$clone->setTitle('Clone of ' . $this->getTitle());
$clone->setDescription($this->getDescription());
$clone->setOwner($newOwner);
$clone->setCreated(time());
$clone->setLastInteraction(0);
$clone->setExpire($this->getExpire());
$clone->setDeleted(0);
$clone->setAccess(self::ACCESS_PRIVATE);
$clone->setAnonymous(0);
$clone->setAllowComment($this->getAllowComment());
$clone->setAllowMaybe($this->getAllowMaybe());
$clone->setAllowProposals($this->getAllowProposals());
$clone->setProposalsExpire($this->getProposalsExpire());
$clone->setVoteLimit($this->getVoteLimit());
$clone->setOptionLimit($this->getOptionLimit());
$clone->setShowResults($this->getShowResults());
$clone->setAdminAccess($this->getAdminAccess());
$clone->setHideBookedUp($this->getHideBookedUp());
$clone->setUseNo($this->getUseNo());
$clone->setMiscSettings($this->getMiscSettings());
$clone->setTimezoneName($this->getTimezoneName());
return $clone;
}

/**
* @return array
*
Expand Down
4 changes: 2 additions & 2 deletions lib/Service/DiffService.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,12 @@ private function extractNewValues($diff, &$newValues): void {
foreach ($diff as $key => $value) {
if (is_array($value)) {
// If 'new' exists, add it to the correct position in the structure
if (isset($value['new'])) {
if (array_key_exists('new', $value)) {
$newValues[$key] = $value['new'];
}

// If the element is an array and the key isn't set yet, initialize it
if (!isset($newValues[$key])) {
if (!array_key_exists($key, $newValues)) {
$newValues[$key] = [];
}

Expand Down
4 changes: 1 addition & 3 deletions lib/Service/PollService.php
Original file line number Diff line number Diff line change
Expand Up @@ -411,9 +411,7 @@ public function clone(int $pollId): Poll {
throw new ForbiddenException('Poll creation is disabled');
}

$this->poll = clone $origin;

$this->poll->setOwner($this->userSession->getCurrentUserId());
$this->poll = $origin->createClone($this->userSession->getCurrentUserId());

$this->poll = $this->pollMapper->insert($this->poll);
$this->eventDispatcher->dispatchTyped(new PollCreatedEvent($this->poll));
Expand Down
Loading