Compare commits

...

43 Commits

Author SHA1 Message Date
Julius Härtl
869aba34d9 Bump version to 1.2.9
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-09-14 21:12:58 +02:00
Julius Härtl
7cde6672a4 Merge pull request #3319 from nextcloud/backport/3316/stable1.2
[stable1.2] Additional check for stacks
2021-09-14 21:11:24 +02:00
Julius Härtl
1e51113d90 Additional check for stacks
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-09-14 21:03:10 +02:00
Julius Härtl
2bed4eb18d Merge pull request #3226 from nextcloud/backport/3217/stable1.2
[stable1.2] Additional circle level check
2021-08-04 18:41:01 +02:00
Julius Härtl
42dac6e187 Check circle level
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-08-04 08:28:35 +02:00
Julius Härtl
a0dc7d2e6a Merge pull request #3228 from nextcloud/tests/stable1.2 2021-08-03 19:28:48 +02:00
Julius Härtl
1463175981 Pin CI to mariadb 10.5
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-08-03 19:22:11 +02:00
Julius Härtl
7bdadc4b03 use ILogger for stable1.2
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-08-03 19:22:11 +02:00
Julius Härtl
b9ee020732 Bump version to 1.2.8
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-07-09 12:13:43 +02:00
Julius Härtl
ff7bf7d0cc Catch any error during circle detail fetching
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-07-09 12:13:43 +02:00
Julius Härtl
17cf314738 Merge pull request #3163 from nextcloud/backport/3151/stable1.2
[stable1.2] Always log generic exceptions
2021-07-05 16:21:24 +02:00
Julius Härtl
76b20a9edc Always log generic exceptions
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-07-02 15:55:18 +00:00
Christoph Wurst
16a43c1b33 Merge pull request #3090 from nextcloud/bugfix/noid/load-attachments
[stable1.2] Always fetch attachments
2021-06-07 13:14:26 +02:00
Julius Härtl
19edbfe777 Trigger attachment loading when switching the card sidebar
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-05-27 13:30:18 +02:00
Julius Härtl
df8d398284 Bump version to 1.2.7
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-04-20 11:36:37 +02:00
Julius Härtl
8cbc18dc31 Merge pull request #2993 from nextcloud/backport/2950/stable1.2 2021-04-20 07:44:30 -01:00
Julius Härtl
493907fe76 Fix tests
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-04-20 10:17:12 +02:00
Julius Härtl
5ae22ec6de Filter out current user when emitting share notifications to groups
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-04-20 10:17:12 +02:00
Julius Härtl
0b2af720a9 Remove notification on unshare/unassign and add type hints
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-04-20 10:17:12 +02:00
Julius Härtl
3911f1654e Remove app code check
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-04-20 10:16:31 +02:00
Julius Härtl
26cbf186f9 Merge pull request #3009 from nextcloud/backport/3005/stable1.2
[stable1.2] Do not query the lookupserver when looking for sharees
2021-04-19 10:38:28 -01:00
Julius Härtl
e7e42a52d7 Merge pull request #3007 from nextcloud/backport/3003/stable1.2
[stable1.2] Only import debounce
2021-04-19 09:02:34 -01:00
Julius Härtl
7b287ff4d3 Do not query the lookupserver when looking for sharees
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-04-19 10:02:18 +00:00
Julius Härtl
1ba007c070 Only import debounce
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-04-19 09:22:53 +00:00
Christoph Wurst
0055527a49 Merge pull request #2985 from nextcloud/backport/2983/stable1.2
[stable1.2] Fix codemirror description width
2021-04-14 20:38:37 +02:00
Julius Härtl
cae007ad27 Fix codemirror description width
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-04-14 18:08:30 +00:00
Julius Härtl
cbc6907f0a Merge pull request #2966 from nextcloud/backport/2964/stable1.2
[stable1.2] Fix navigating to board details
2021-04-13 08:01:10 -01:00
Julius Härtl
4753291390 Fix navigating to board details (fix #2951)
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-04-12 14:11:18 +00:00
Julius Härtl
a14a33d69c Bump version to 1.2.6
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-04-07 18:43:30 +02:00
Julius Härtl
fd968d95d7 Merge pull request #2947 from nextcloud/backport/2793/stable1.2
[stable1.2] fix desc save bug
2021-04-07 18:41:27 +02:00
Jakob Röhrl
a34c3b0667 fix desc save bug
Signed-off-by: Jakob Röhrl <jakob.roehrl@web.de>
2021-04-07 08:38:15 +02:00
Julius Härtl
418536ceb1 Merge pull request #2925 from nextcloud/backport/2923/stable1.2
[stable1.2] Avoid reusing the existing route object to make navigation work properly
2021-03-29 14:13:18 +02:00
Julius Härtl
4be27cc653 Avoid reusing the existing route object to make navigation work properly
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-03-29 12:00:47 +00:00
Julius Härtl
1e06aef4e6 Bump version to 1.2.5
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-03-05 15:54:06 +01:00
Julius Härtl
4362fdf200 Merge pull request #2860 from nextcloud/backport/2823/stable1.2
[stable1.2] Properly pass the user to fetch circles when calling through occ
2021-03-05 15:49:24 +01:00
Julius Härtl
d14b4f5853 Properly pass the user to fetch circles when calling through occ
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-03-05 14:41:42 +00:00
Julius Härtl
f289ab2d63 Merge pull request #2845 from nextcloud/backport/2843/stable1.2 2021-03-05 15:39:46 +01:00
Julius Härtl
0ec265b1fb Use proper debounce on the sharing input
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-03-05 13:39:12 +01:00
Julius Härtl
3836363ed4 Search by mail on the board sharing input
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-03-05 13:39:12 +01:00
Julius Härtl
517b3cbaf3 Merge pull request #2850 from nextcloud/backport/2847/stable1.2
[stable1.2] Switch to Content-Disposition attachment and check for sane mimetypes
2021-03-05 13:38:14 +01:00
Julius Härtl
5fb0c401c8 Switch to Content-Disposition attachment and check for sane mimetypes
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-03-04 11:22:47 +01:00
Julius Härtl
0b06c0d180 Merge pull request #2851 from nextcloud/ci/github-actions-ubuntu-update
[stable1.2] Let CI pass again
2021-03-04 09:34:06 +01:00
Julius Härtl
aa38264d7b Properly setup github actions due to switch to ubuntu 20.04
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2021-03-04 09:21:36 +01:00
28 changed files with 232 additions and 649 deletions

View File

@@ -1,55 +0,0 @@
name: Nextcloud app code check
on:
pull_request:
push:
branches:
- master
- stable*
env:
APP_NAME: deck
jobs:
unit-tests:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: ['7.4']
server-versions: ['master', 'stable18', 'stable19', 'stable20']
name: AppCode check php${{ matrix.php-versions }}-${{ matrix.server-versions }}
steps:
- name: Checkout server
uses: actions/checkout@v2
with:
repository: nextcloud/server
ref: ${{ matrix.server-versions }}
- name: Checkout submodules
shell: bash
run: |
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
- name: Checkout app
uses: actions/checkout@v2
with:
path: apps/${{ env.APP_NAME }}
- name: Set up php ${{ matrix.php-versions }}
uses: shivammathur/setup-php@v1
with:
php-version: ${{ matrix.php-versions }}
tools: phpunit
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite
- name: Checkout app
uses: actions/checkout@v2
with:
path: apps/${{ env.APP_NAME }}
- name: App code check
run: php occ app:check-code ${{ env.APP_NAME }}

View File

@@ -6,7 +6,7 @@ on:
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-18.04
strategy: strategy:
matrix: matrix:

View File

@@ -34,7 +34,7 @@ jobs:
POSTGRES_DB: nextcloud POSTGRES_DB: nextcloud
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5 options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
mysql: mysql:
image: mariadb image: mariadb:10.5
ports: ports:
- 4444:3306/tcp - 4444:3306/tcp
env: env:

View File

@@ -35,7 +35,7 @@ jobs:
POSTGRES_DB: nextcloud POSTGRES_DB: nextcloud
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5 options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
mysql: mysql:
image: mariadb image: mariadb:10.5
ports: ports:
- 4444:3306/tcp - 4444:3306/tcp
env: env:
@@ -66,7 +66,7 @@ jobs:
with: with:
php-version: ${{ matrix.php-versions }} php-version: ${{ matrix.php-versions }}
tools: phpunit tools: phpunit
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql, zip, gd
coverage: none coverage: none
- name: Set up PHPUnit - name: Set up PHPUnit

View File

@@ -1,6 +1,49 @@
# Changelog # Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## 1.2.9
### Other
- #3319 Additional check for stacks
- #3226 Additional circle level check
## 1.2.8
### Fixed
* [#3090](https://github.com/nextcloud/deck/pull/3090) Always fetch attachments
* [#3163](https://github.com/nextcloud/deck/pull/3163) Always log generic exceptions
## 1.2.7
### Fixed
* [#2966](https://github.com/nextcloud/deck/pull/2966) Fix navigating to board details
* [#2985](https://github.com/nextcloud/deck/pull/2985) Fix codemirror description width
* [#2993](https://github.com/nextcloud/deck/pull/2993) Remove notification on unshare and add type hints
* [#3007](https://github.com/nextcloud/deck/pull/3007) Only import debounce
* [#3009](https://github.com/nextcloud/deck/pull/3009) Do not query the lookupserver when looking for sharees
## 1.2.6 - 2021-04-07
### Fixed
* [#2925](https://github.com/nextcloud/deck/pull/2925) Avoid reusing the existing route object to make navigation work properly
* [#2947](https://github.com/nextcloud/deck/pull/2947) Fix bug when saving the description
## 1.2.5 - 2021-03-05
### Fixed
* [#2845](https://github.com/nextcloud/deck/pull/2845) Search by mail on the board sharing input
* [#2850](https://github.com/nextcloud/deck/pull/2850) Switch to Content-Disposition attachment and check for sane mimetypes
* [#2860](https://github.com/nextcloud/deck/pull/2860) Properly pass the user to fetch circles when calling through occ
## 1.2.4 - 2021-02-02 ## 1.2.4 - 2021-02-02
### Fixed ### Fixed
@@ -131,31 +174,31 @@ All notable changes to this project will be documented in this file.
### Fixed ### Fixed
* [#2116](https://github.com/nextcloud/deck/pull/2116) Fix navigation layout issues @juliushaertl * [#2116](https://github.com/nextcloud/deck/pull/2116) Fix navigation layout issues
* [#2118](https://github.com/nextcloud/deck/pull/2118) Use proper parameter when handling attachments @juliushaertl * [#2118](https://github.com/nextcloud/deck/pull/2118) Use proper parameter when handling attachments
## 1.0.4 - 2020-06-26 ## 1.0.4 - 2020-06-26
### Fixed ### Fixed
* [#2062](https://github.com/nextcloud/deck/pull/2062) Fix saving card description after toggling checkboxes @juliushaertl * [#2062](https://github.com/nextcloud/deck/pull/2062) Fix saving card description after toggling checkboxes
* [#2065](https://github.com/nextcloud/deck/pull/2065) Adding CSS rule for Markdown Blockquotes @reox * [#2065](https://github.com/nextcloud/deck/pull/2065) Adding CSS rule for Markdown Blockquotes @reox
* [#2059](https://github.com/nextcloud/deck/pull/2059) Fix fetching attachments on card change @juliushaertl * [#2059](https://github.com/nextcloud/deck/pull/2059) Fix fetching attachments on card change
* [#2060](https://github.com/nextcloud/deck/pull/2060) Use mixing for relative date in card sidebar @juliushaertl * [#2060](https://github.com/nextcloud/deck/pull/2060) Use mixing for relative date in card sidebar
## 1.0.3 - 2020-06-19 ## 1.0.3 - 2020-06-19
### Fixed ### Fixed
* [#2019](https://github.com/nextcloud/deck/pull/2019) Remove old global css rule @juliushaertl * [#2019](https://github.com/nextcloud/deck/pull/2019) Remove old global css rule
* [#2020](https://github.com/nextcloud/deck/pull/2020) Fix navigation issue with leftover nodes @juliushaertl * [#2020](https://github.com/nextcloud/deck/pull/2020) Fix navigation issue with leftover nodes
* [#2021](https://github.com/nextcloud/deck/pull/2021) Fix description issues @juliushaertl * [#2021](https://github.com/nextcloud/deck/pull/2021) Fix description issues
* [#2022](https://github.com/nextcloud/deck/pull/2022) Fix replyto issues with the comments API @juliushaertl * [#2022](https://github.com/nextcloud/deck/pull/2022) Fix replyto issues with the comments API
* [#2027](https://github.com/nextcloud/deck/pull/2027) Allow to unassign current user from card @juliushaertl * [#2027](https://github.com/nextcloud/deck/pull/2027) Allow to unassign current user from card
* [#2029](https://github.com/nextcloud/deck/pull/2029) Fix wording : stack -> list @cloud2018 * [#2029](https://github.com/nextcloud/deck/pull/2029) Fix wording : stack -> list @cloud2018
* [#2032](https://github.com/nextcloud/deck/pull/2032) Force order by id as second sorting key @juliushaertl * [#2032](https://github.com/nextcloud/deck/pull/2032) Force order by id as second sorting key
* [#2045](https://github.com/nextcloud/deck/pull/2045) Improve label styling @juliushaertl * [#2045](https://github.com/nextcloud/deck/pull/2045) Improve label styling
* [#2010](https://github.com/nextcloud/deck/pull/2010) User documentation fixes @Nyco * [#2010](https://github.com/nextcloud/deck/pull/2010) User documentation fixes @Nyco
* [#1998](https://github.com/nextcloud/deck/pull/1998) Add Checklist explaination to the doc @4rnoP * [#1998](https://github.com/nextcloud/deck/pull/1998) Add Checklist explaination to the doc @4rnoP

View File

@@ -1,6 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0" encoding="utf-8"?>
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" <info xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>deck</id> <id>deck</id>
<name>Deck</name> <name>Deck</name>
<summary>Personal planning and team project organization</summary> <summary>Personal planning and team project organization</summary>
@@ -17,12 +16,12 @@
- 🚀 Get your project organized - 🚀 Get your project organized
</description> </description>
<version>1.2.4</version> <version>1.2.9</version>
<licence>agpl</licence> <licence>agpl</licence>
<author>Julius Härtl</author> <author>Julius Härtl</author>
<namespace>Deck</namespace> <namespace>Deck</namespace>
<types> <types>
<dav /> <dav/>
</types> </types>
<category>organization</category> <category>organization</category>
<category>office</category> <category>office</category>
@@ -36,7 +35,7 @@
<database min-version="9.4">pgsql</database> <database min-version="9.4">pgsql</database>
<database>sqlite</database> <database>sqlite</database>
<database min-version="5.5">mysql</database> <database min-version="5.5">mysql</database>
<nextcloud min-version="18" max-version="20" /> <nextcloud min-version="18" max-version="20"/>
</dependencies> </dependencies>
<background-jobs> <background-jobs>
<job>OCA\Deck\Cron\DeleteCron</job> <job>OCA\Deck\Cron\DeleteCron</job>

View File

@@ -35,6 +35,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
private $stackMapper; private $stackMapper;
private $userManager; private $userManager;
private $groupManager; private $groupManager;
private $logger;
private $circlesEnabled; private $circlesEnabled;
@@ -44,7 +45,8 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
AclMapper $aclMapper, AclMapper $aclMapper,
StackMapper $stackMapper, StackMapper $stackMapper,
IUserManager $userManager, IUserManager $userManager,
IGroupManager $groupManager IGroupManager $groupManager,
ILogger $logger
) { ) {
parent::__construct($db, 'deck_boards', Board::class); parent::__construct($db, 'deck_boards', Board::class);
$this->labelMapper = $labelMapper; $this->labelMapper = $labelMapper;
@@ -52,6 +54,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
$this->stackMapper = $stackMapper; $this->stackMapper = $stackMapper;
$this->userManager = $userManager; $this->userManager = $userManager;
$this->groupManager = $groupManager; $this->groupManager = $groupManager;
$this->logger = $logger;
$this->circlesEnabled = \OC::$server->getAppManager()->isEnabledForUser('circles'); $this->circlesEnabled = \OC::$server->getAppManager()->isEnabledForUser('circles');
} }
@@ -159,7 +162,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
} }
$circles = array_map(function ($circle) { $circles = array_map(function ($circle) {
return $circle->getUniqueId(); return $circle->getUniqueId();
}, \OCA\Circles\Api\v1\Circles::joinedCircles('', true)); }, \OCA\Circles\Api\v1\Circles::joinedCircles($userId, true));
if (count($circles) === 0) { if (count($circles) === 0) {
return []; return [];
} }
@@ -238,7 +241,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
if ($user !== null) { if ($user !== null) {
return new User($user); return new User($user);
} }
\OC::$server->getLogger()->debug('User ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant()); $this->logger->debug('User ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant());
return null; return null;
} }
if ($acl->getType() === Acl::PERMISSION_TYPE_GROUP) { if ($acl->getType() === Acl::PERMISSION_TYPE_GROUP) {
@@ -246,7 +249,7 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
if ($group !== null) { if ($group !== null) {
return new Group($group); return new Group($group);
} }
\OC::$server->getLogger()->debug('Group ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant()); $this->logger->debug('Group ' . $acl->getId() . ' not found when mapping acl ' . $acl->getParticipant());
return null; return null;
} }
if ($acl->getType() === Acl::PERMISSION_TYPE_CIRCLE) { if ($acl->getType() === Acl::PERMISSION_TYPE_CIRCLE) {
@@ -258,11 +261,12 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
if ($circle) { if ($circle) {
return new Circle($circle); return new Circle($circle);
} }
} catch (\Exception $e) { } catch (\Throwable $e) {
$this->logger->error('Failed to get circle details when building ACL', ['exception' => $e]);
} }
return null; return null;
} }
\OC::$server->getLogger()->log(ILogger::WARN, 'Unknown permission type for mapping acl ' . $acl->getId()); $this->logger->warning('Unknown permission type for mapping acl ' . $acl->getId());
return null; return null;
}); });
} }

View File

@@ -98,9 +98,7 @@ class ExceptionMiddleware extends Middleware {
'status' => 500, 'status' => 500,
'message' => $exception->getMessage() 'message' => $exception->getMessage()
]; ];
if ($this->config->getSystemValue('loglevel', Util::WARN) === Util::DEBUG) { $this->logger->logException($exception);
$this->logger->logException($exception);
}
if ($this->config->getSystemValue('debug', true) === true) { if ($this->config->getSystemValue('debug', true) === true) {
$response['exception'] = (array) $exception; $response['exception'] = (array) $exception;
} }

View File

@@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
/** /**
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net> * @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
* *
@@ -24,19 +27,24 @@
namespace OCA\Deck\Notification; namespace OCA\Deck\Notification;
use DateTime; use DateTime;
use Exception;
use OCA\Deck\AppInfo\Application; use OCA\Deck\AppInfo\Application;
use OCA\Deck\Db\Acl; use OCA\Deck\Db\Acl;
use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\AssignmentMapper;
use OCA\Deck\Db\Board; use OCA\Deck\Db\Board;
use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\BoardMapper;
use OCA\Deck\Db\Card;
use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\CardMapper;
use OCA\Deck\Db\User; use OCA\Deck\Db\User;
use OCA\Deck\Service\ConfigService; use OCA\Deck\Service\ConfigService;
use OCA\Deck\Service\PermissionService; use OCA\Deck\Service\PermissionService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Db\MultipleObjectsReturnedException;
use OCP\Comments\IComment; use OCP\Comments\IComment;
use OCP\IConfig; use OCP\IConfig;
use OCP\IGroupManager; use OCP\IGroupManager;
use OCP\Notification\IManager; use OCP\Notification\IManager;
use OCP\Notification\INotification;
class NotificationHelper { class NotificationHelper {
@@ -80,10 +88,10 @@ class NotificationHelper {
} }
/** /**
* @param $card * @throws DoesNotExistException
* @throws \OCP\AppFramework\Db\DoesNotExistException * @throws Exception thrown on invalid due date
*/ */
public function sendCardDuedate($card) { public function sendCardDuedate(Card $card): void {
// check if notification has already been sent // check if notification has already been sent
// ideally notifications should not be deleted once seen by the user so we can // ideally notifications should not be deleted once seen by the user so we can
// also deliver due date notifications for users who have been added later to a board // also deliver due date notifications for users who have been added later to a board
@@ -117,7 +125,7 @@ class NotificationHelper {
$notification $notification
->setApp('deck') ->setApp('deck')
->setUser((string)$user->getUID()) ->setUser((string)$user->getUID())
->setObject('card', $card->getId()) ->setObject('card', (string)$card->getId())
->setSubject('card-overdue', [ ->setSubject('card-overdue', [
$card->getTitle(), $board->getTitle() $card->getTitle(), $board->getTitle()
]) ])
@@ -128,25 +136,29 @@ class NotificationHelper {
$this->cardMapper->markNotified($card); $this->cardMapper->markNotified($card);
} }
public function markDuedateAsRead($card) { public function markDuedateAsRead(Card $card): void {
$notification = $this->notificationManager->createNotification(); $notification = $this->notificationManager->createNotification();
$notification $notification
->setApp('deck') ->setApp('deck')
->setObject('card', $card->getId()) ->setObject('card', (string)$card->getId())
->setSubject('card-overdue', []); ->setSubject('card-overdue', []);
$this->notificationManager->markProcessed($notification); $this->notificationManager->markProcessed($notification);
} }
public function sendCardAssigned($card, $userId) { public function sendCardAssigned(Card $card, string $userId): void {
$boardId = $this->cardMapper->findBoardId($card->getId()); $boardId = $this->cardMapper->findBoardId($card->getId());
$board = $this->getBoard($boardId); try {
$board = $this->getBoard($boardId);
} catch (Exception $e) {
return;
}
$notification = $this->notificationManager->createNotification(); $notification = $this->notificationManager->createNotification();
$notification $notification
->setApp('deck') ->setApp('deck')
->setUser((string) $userId) ->setUser($userId)
->setDateTime(new DateTime()) ->setDateTime(new DateTime())
->setObject('card', $card->getId()) ->setObject('card', (string)$card->getId())
->setSubject('card-assigned', [ ->setSubject('card-assigned', [
$card->getTitle(), $card->getTitle(),
$board->getTitle(), $board->getTitle(),
@@ -155,29 +167,56 @@ class NotificationHelper {
$this->notificationManager->notify($notification); $this->notificationManager->notify($notification);
} }
public function markCardAssignedAsRead(Card $card, string $userId): void {
$notification = $this->notificationManager->createNotification();
$notification
->setApp('deck')
->setUser($userId)
->setObject('card', (string)$card->getId())
->setSubject('card-assigned', []);
$this->notificationManager->markProcessed($notification);
}
/** /**
* Send notifications that a board was shared with a user/group * Send notifications that a board was shared with a user/group
*
* @param $boardId
* @param Acl $acl
* @throws \InvalidArgumentException
*/ */
public function sendBoardShared($boardId, $acl) { public function sendBoardShared(int $boardId, Acl $acl, bool $markAsRead = false): void {
$board = $this->getBoard($boardId); try {
$board = $this->getBoard($boardId);
} catch (Exception $e) {
return;
}
if ($acl->getType() === Acl::PERMISSION_TYPE_USER) { if ($acl->getType() === Acl::PERMISSION_TYPE_USER) {
$notification = $this->generateBoardShared($board, $acl->getParticipant()); $notification = $this->generateBoardShared($board, $acl->getParticipant());
$this->notificationManager->notify($notification); if ($markAsRead) {
$this->notificationManager->markProcessed($notification);
} else {
$notification->setDateTime(new DateTime());
$this->notificationManager->notify($notification);
}
} }
if ($acl->getType() === Acl::PERMISSION_TYPE_GROUP) { if ($acl->getType() === Acl::PERMISSION_TYPE_GROUP) {
$group = $this->groupManager->get($acl->getParticipant()); $group = $this->groupManager->get($acl->getParticipant());
if ($group === null) {
return;
}
foreach ($group->getUsers() as $user) { foreach ($group->getUsers() as $user) {
if ($user->getUID() === $this->currentUser) {
continue;
}
$notification = $this->generateBoardShared($board, $user->getUID()); $notification = $this->generateBoardShared($board, $user->getUID());
$this->notificationManager->notify($notification); if ($markAsRead) {
$this->notificationManager->markProcessed($notification);
} else {
$notification->setDateTime(new DateTime());
$this->notificationManager->notify($notification);
}
} }
} }
} }
public function sendMention(IComment $comment) { public function sendMention(IComment $comment): void {
foreach ($comment->getMentions() as $mention) { foreach ($comment->getMentions() as $mention) {
$card = $this->cardMapper->find($comment->getObjectId()); $card = $this->cardMapper->find($comment->getObjectId());
$boardId = $this->cardMapper->findBoardId($card->getId()); $boardId = $this->cardMapper->findBoardId($card->getId());
@@ -194,27 +233,22 @@ class NotificationHelper {
} }
/** /**
* @param $boardId * @throws DoesNotExistException
* @return Board * @throws MultipleObjectsReturnedException
* @throws \OCP\AppFramework\Db\DoesNotExistException
*/ */
private function getBoard($boardId, bool $withLabels = false, bool $withAcl = false) { private function getBoard(int $boardId, bool $withLabels = false, bool $withAcl = false): Board {
if (!array_key_exists($boardId, $this->boards)) { if (!array_key_exists($boardId, $this->boards)) {
$this->boards[$boardId] = $this->boardMapper->find($boardId, $withLabels, $withAcl); $this->boards[$boardId] = $this->boardMapper->find($boardId, $withLabels, $withAcl);
} }
return $this->boards[$boardId]; return $this->boards[$boardId];
} }
/** private function generateBoardShared(Board $board, string $userId): INotification {
* @param Board $board
*/
private function generateBoardShared($board, $userId) {
$notification = $this->notificationManager->createNotification(); $notification = $this->notificationManager->createNotification();
$notification $notification
->setApp('deck') ->setApp('deck')
->setUser((string) $userId) ->setUser($userId)
->setDateTime(new DateTime()) ->setObject('board', (string)$board->getId())
->setObject('board', $board->getId())
->setSubject('board-shared', [$board->getTitle(), $this->currentUser]); ->setSubject('board-shared', [$board->getTitle(), $this->currentUser]);
return $notification; return $notification;
} }

View File

@@ -74,6 +74,8 @@ class AssignmentService {
* @var IEventDispatcher * @var IEventDispatcher
*/ */
private $eventDispatcher; private $eventDispatcher;
/** @var string|null */
private $currentUser;
public function __construct( public function __construct(
PermissionService $permissionService, PermissionService $permissionService,
@@ -138,8 +140,7 @@ class AssignmentService {
} }
if ($userId !== $this->currentUser) { if ($type === Assignment::TYPE_USER && $userId !== $this->currentUser) {
/* Notifyuser about the card assignment */
$this->notificationHelper->sendCardAssigned($card, $userId); $this->notificationHelper->sendCardAssigned($card, $userId);
} }
@@ -185,6 +186,9 @@ class AssignmentService {
$assignment = $this->assignedUsersMapper->delete($assignment); $assignment = $this->assignedUsersMapper->delete($assignment);
$card = $this->cardMapper->find($cardId); $card = $this->cardMapper->find($cardId);
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_USER_UNASSIGN, ['assigneduser' => $userId]); $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_USER_UNASSIGN, ['assigneduser' => $userId]);
if ($type === Assignment::TYPE_USER && $userId !== $this->currentUser) {
$this->notificationHelper->markCardAssignedAsRead($card, $userId);
}
$this->changeHelper->cardChanged($cardId); $this->changeHelper->cardChanged($cardId);
$this->eventDispatcher->dispatch( $this->eventDispatcher->dispatch(

View File

@@ -532,11 +532,10 @@ class BoardService {
$acl->setPermissionShare($share); $acl->setPermissionShare($share);
$acl->setPermissionManage($manage); $acl->setPermissionManage($manage);
/* Notify users about the shared board */
$this->notificationHelper->sendBoardShared($boardId, $acl);
$newAcl = $this->aclMapper->insert($acl); $newAcl = $this->aclMapper->insert($acl);
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $newAcl, ActivityManager::SUBJECT_BOARD_SHARE); $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $newAcl, ActivityManager::SUBJECT_BOARD_SHARE);
$this->notificationHelper->sendBoardShared((int)$boardId, $newAcl);
$this->boardMapper->mapAcl($newAcl); $this->boardMapper->mapAcl($newAcl);
$this->changeHelper->boardChanged($boardId); $this->changeHelper->boardChanged($boardId);
@@ -628,6 +627,7 @@ class BoardService {
} }
} }
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $acl, ActivityManager::SUBJECT_BOARD_UNSHARE); $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $acl, ActivityManager::SUBJECT_BOARD_UNSHARE);
$this->notificationHelper->sendBoardShared($acl->getBoardId(), $acl, true);
$this->changeHelper->boardChanged($acl->getBoardId()); $this->changeHelper->boardChanged($acl->getBoardId());
$version = \OCP\Util::getVersion()[0]; $version = \OCP\Util::getVersion()[0];

View File

@@ -240,6 +240,7 @@ class CardService {
$card->setDeletedAt(time()); $card->setDeletedAt(time());
$this->cardMapper->update($card); $this->cardMapper->update($card);
$this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_DELETE); $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_DELETE);
$this->notificationHelper->markDuedateAsRead($card);
$this->changeHelper->cardChanged($card->getId(), false); $this->changeHelper->cardChanged($card->getId(), false);
$this->eventDispatcher->dispatch( $this->eventDispatcher->dispatch(
@@ -322,6 +323,15 @@ class CardService {
$card->setOrder($order); $card->setOrder($order);
$card->setOwner($owner); $card->setOwner($owner);
$card->setDuedate($duedate); $card->setDuedate($duedate);
$resetDuedateNotification = false;
if (
$card->getDuedate() === null ||
(new \DateTime($card->getDuedate())) != (new \DateTime($changes->getBefore()->getDuedate()))
) {
$card->setNotified(false);
$resetDuedateNotification = true;
}
if ($deletedAt !== null) { if ($deletedAt !== null) {
$card->setDeletedAt($deletedAt); $card->setDeletedAt($deletedAt);
} }
@@ -341,6 +351,9 @@ class CardService {
$card = $this->cardMapper->update($card); $card = $this->cardMapper->update($card);
if ($resetDuedateNotification) {
$this->notificationHelper->markDuedateAsRead($card);
}
$this->changeHelper->cardChanged($card->getId(), true); $this->changeHelper->cardChanged($card->getId(), true);
$this->eventDispatcher->dispatch( $this->eventDispatcher->dispatch(

View File

@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace OCA\Deck\Service; namespace OCA\Deck\Service;
use OCA\Circles\Api\v1\Circles;
use OCP\App\IAppManager; use OCP\App\IAppManager;
/** /**
@@ -53,8 +54,8 @@ class CirclesService {
} }
try { try {
\OCA\Circles\Api\v1\Circles::getMember($circleId, $userId, 1, true); $member = \OCA\Circles\Api\v1\Circles::getMember($circleId, $userId, 1, true);
return true; return $member->getLevel() >= Circles::LEVEL_MEMBER;
} catch (\Exception $e) { } catch (\Exception $e) {
} }
return false; return false;

View File

@@ -27,10 +27,9 @@ use OCA\Deck\Db\Attachment;
use OCA\Deck\Db\AttachmentMapper; use OCA\Deck\Db\AttachmentMapper;
use OCA\Deck\StatusException; use OCA\Deck\StatusException;
use OCA\Deck\Exceptions\ConflictException; use OCA\Deck\Exceptions\ConflictException;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\FileDisplayResponse;
use OCP\AppFramework\Http\StreamResponse; use OCP\AppFramework\Http\StreamResponse;
use OCP\Files\IAppData; use OCP\Files\IAppData;
use OCP\Files\IMimeTypeDetector;
use OCP\Files\IRootFolder; use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException; use OCP\Files\NotFoundException;
use OCP\Files\NotPermittedException; use OCP\Files\NotPermittedException;
@@ -49,6 +48,7 @@ class FileService implements IAttachmentService {
private $rootFolder; private $rootFolder;
private $config; private $config;
private $attachmentMapper; private $attachmentMapper;
private $mimeTypeDetector;
public function __construct( public function __construct(
IL10N $l10n, IL10N $l10n,
@@ -57,7 +57,8 @@ class FileService implements IAttachmentService {
ILogger $logger, ILogger $logger,
IRootFolder $rootFolder, IRootFolder $rootFolder,
IConfig $config, IConfig $config,
AttachmentMapper $attachmentMapper AttachmentMapper $attachmentMapper,
IMimeTypeDetector $mimeTypeDetector
) { ) {
$this->l10n = $l10n; $this->l10n = $l10n;
$this->appData = $appData; $this->appData = $appData;
@@ -66,6 +67,7 @@ class FileService implements IAttachmentService {
$this->rootFolder = $rootFolder; $this->rootFolder = $rootFolder;
$this->config = $config; $this->config = $config;
$this->attachmentMapper = $attachmentMapper; $this->attachmentMapper = $attachmentMapper;
$this->mimeTypeDetector = $mimeTypeDetector;
} }
/** /**
@@ -225,27 +227,14 @@ class FileService implements IAttachmentService {
/** /**
* @param Attachment $attachment * @param Attachment $attachment
* @return FileDisplayResponse|\OCP\AppFramework\Http\Response|StreamResponse * @return StreamResponse
* @throws \Exception * @throws \Exception
*/ */
public function display(Attachment $attachment) { public function display(Attachment $attachment) {
$file = $this->getFileFromRootFolder($attachment); $file = $this->getFileFromRootFolder($attachment);
if (method_exists($file, 'fopen')) { $response = new StreamResponse($file->fopen('rb'));
$response = new StreamResponse($file->fopen('r')); $response->addHeader('Content-Disposition', 'attachment; filename="' . rawurldecode($file->getName()) . '"');
$response->addHeader('Content-Disposition', 'inline; filename="' . rawurldecode($file->getName()) . '"'); $response->addHeader('Content-Type', $this->mimeTypeDetector->getSecureMimeType($file->getMimeType()));
} else {
$response = new FileDisplayResponse($file);
}
// We need those since otherwise chrome won't show the PDF file with CSP rule object-src 'none'
// https://bugs.chromium.org/p/chromium/issues/detail?id=271452
$policy = new ContentSecurityPolicy();
$policy->addAllowedObjectDomain('\'self\'');
$policy->addAllowedObjectDomain('blob:');
$policy->addAllowedMediaDomain('\'self\'');
$policy->addAllowedMediaDomain('blob:');
$response->setContentSecurityPolicy($policy);
$response->addHeader('Content-Type', $file->getMimeType());
return $response; return $response;
} }

View File

@@ -23,6 +23,7 @@
namespace OCA\Deck\Service; namespace OCA\Deck\Service;
use OCA\Circles\Model\Member;
use OCA\Deck\Db\Acl; use OCA\Deck\Db\Acl;
use OCA\Deck\Db\AclMapper; use OCA\Deck\Db\AclMapper;
use OCA\Deck\Db\Board; use OCA\Deck\Db\Board;
@@ -194,8 +195,8 @@ class PermissionService {
if ($this->circlesEnabled && $acl->getType() === Acl::PERMISSION_TYPE_CIRCLE) { if ($this->circlesEnabled && $acl->getType() === Acl::PERMISSION_TYPE_CIRCLE) {
try { try {
\OCA\Circles\Api\v1\Circles::getMember($acl->getParticipant(), $this->userId, 1, true); $member = \OCA\Circles\Api\v1\Circles::getMember($acl->getParticipant(), $this->userId, 1, true);
return $acl->getPermission($permission); return $member->getLevel() >= Member::LEVEL_MEMBER && $acl->getPermission($permission);
} catch (\Exception $e) { } catch (\Exception $e) {
$this->logger->info('Member not found in circle that was accessed. This should not happen.'); $this->logger->info('Member not found in circle that was accessed. This should not happen.');
} }

View File

@@ -114,6 +114,7 @@ class StackService {
throw new BadRequestException('stack id must be a number'); throw new BadRequestException('stack id must be a number');
} }
$this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_READ);
$stack = $this->stackMapper->find($stackId); $stack = $this->stackMapper->find($stackId);
$cards = $this->cardMapper->findAll($stackId); $cards = $this->cardMapper->findAll($stackId);
foreach ($cards as $cardIndex => $card) { foreach ($cards as $cardIndex => $card) {

View File

@@ -1,7 +1,7 @@
{ {
"name": "deck", "name": "deck",
"description": "", "description": "",
"version": "1.0.0", "version": "1.2.9",
"authors": [ "authors": [
{ {
"name": "Julius Härtl", "name": "Julius Härtl",
@@ -129,4 +129,4 @@
"<rootDir>/node_modules/jest-serializer-vue" "<rootDir>/node_modules/jest-serializer-vue"
] ]
} }
} }

View File

@@ -10,7 +10,7 @@
:loading="isLoading || !!isSearching" :loading="isLoading || !!isSearching"
:disabled="isLoading" :disabled="isLoading"
track-by="multiselectKey" track-by="multiselectKey"
:internal-search="true" :internal-search="false"
@input="clickAddAcl" @input="clickAddAcl"
@search-change="asyncFind"> @search-change="asyncFind">
<template #noOptions> <template #noOptions>
@@ -73,6 +73,7 @@ import { CollectionList } from 'nextcloud-vue-collections'
import { mapGetters, mapState } from 'vuex' import { mapGetters, mapState } from 'vuex'
import { getCurrentUser } from '@nextcloud/auth' import { getCurrentUser } from '@nextcloud/auth'
import { showError } from '@nextcloud/dialogs' import { showError } from '@nextcloud/dialogs'
import debounce from 'lodash/debounce'
export default { export default {
name: 'SharingTabSidebar', name: 'SharingTabSidebar',
@@ -148,18 +149,13 @@ export default {
this.asyncFind('') this.asyncFind('')
}, },
methods: { methods: {
debouncedFind: debounce(async function(query) {
this.isSearching = true
await this.$store.dispatch('loadSharees', query)
this.isSearching = false
}, 300),
async asyncFind(query) { async asyncFind(query) {
// manual debounce to handle async searching more easily and have more control over the loading state await this.debouncedFind(query)
const timestamp = (new Date()).getTime()
if (!this.isSearching || timestamp > this.isSearching + 300) {
this.isSearching = timestamp
await this.$store.dispatch('loadSharees', query)
// only reset searching flag if the most recent search finished
if (this.isSearching === timestamp) {
this.isSearching = false
}
}
}, },
async clickAddAcl() { async clickAddAcl() {
this.addAclForAPI = { this.addAclForAPI = {

View File

@@ -151,8 +151,13 @@ export default {
} }
}, },
}, },
created() { watch: {
this.$store.dispatch('fetchAttachments', this.cardId) cardId: {
immediate: true,
handler() {
this.$store.dispatch('fetchAttachments', this.cardId)
},
},
}, },
methods: { methods: {
handleUploadFile(event) { handleUploadFile(event) {

View File

@@ -117,7 +117,7 @@
type="deck-card" /> type="deck-card" />
</div> </div>
<Description :key="card.id" :card="card" /> <Description :key="card.id" :card="card" @change="descriptionChanged" />
</div> </div>
</template> </template>
@@ -234,6 +234,9 @@ export default {
this.initialize() this.initialize()
}, },
methods: { methods: {
descriptionChanged(newDesc) {
this.copiedCard.description = newDesc
},
async initialize() { async initialize() {
if (!this.card) { if (!this.card) {
return return
@@ -253,9 +256,6 @@ export default {
} }
}, },
setDue() {
this.$store.dispatch('updateCardDue', this.copiedCard)
},
removeDue() { removeDue() {
this.copiedCard.duedate = null this.copiedCard.duedate = null
this.$store.dispatch('updateCardDue', this.copiedCard) this.$store.dispatch('updateCardDue', this.copiedCard)

View File

@@ -205,6 +205,7 @@ export default {
await this.$store.dispatch('updateCardDesc', { ...this.card, description: this.description }) await this.$store.dispatch('updateCardDesc', { ...this.card, description: this.description })
this.descriptionLastEdit = 0 this.descriptionLastEdit = 0
this.descriptionSaving = false this.descriptionSaving = false
this.$emit('change', this.description)
}, },
updateDescription() { updateDescription() {
this.descriptionLastEdit = Date.now() this.descriptionLastEdit = Date.now()
@@ -292,6 +293,7 @@ h5 {
padding: 0; padding: 0;
background-color: var(--color-main-background); background-color: var(--color-main-background);
color: var(--color-main-text); color: var(--color-main-text);
width: 100%;
} }
.CodeMirror-placeholder { .CodeMirror-placeholder {

View File

@@ -235,9 +235,7 @@ export default {
try { try {
const newBoard = await this.$store.dispatch('cloneBoard', this.board) const newBoard = await this.$store.dispatch('cloneBoard', this.board)
this.loading = false this.loading = false
const route = this.routeTo this.$router.push({ name: 'board', params: { id: newBoard.id } })
route.params.id = newBoard.id
this.$router.push(route)
} catch (e) { } catch (e) {
OC.Notification.showTemporary(t('deck', 'An error occurred')) OC.Notification.showTemporary(t('deck', 'An error occurred'))
console.error(e) console.error(e)
@@ -278,9 +276,7 @@ export default {
) )
}, },
actionDetails() { actionDetails() {
const route = this.routeTo this.$router.push({ name: 'board.details', params: { id: this.board.id } })
route.name = 'board.details'
this.$router.push(route)
}, },
applyEdit(e) { applyEdit(e) {
this.editing = false this.editing = false
@@ -298,11 +294,6 @@ export default {
cancelEdit(e) { cancelEdit(e) {
this.editing = false this.editing = false
}, },
showSidebar() {
const route = this.routeTo
route.name = 'board.details'
this.$router.push(route)
},
async updateSetting(key, value) { async updateSetting(key, value) {
this.updateDueSetting = value this.updateDueSetting = value
const setting = {} const setting = {}

View File

@@ -414,7 +414,8 @@ export default new Vuex.Store({
params.append('search', query) params.append('search', query)
params.append('format', 'json') params.append('format', 'json')
params.append('perPage', 20) params.append('perPage', 20)
params.append('itemType', [0, 1, 7]) params.append('itemType', [0, 1, 4, 7])
params.append('lookup', false)
const response = await axios.get(generateOcsUrl('apps/files_sharing/api/v1') + 'sharees', { params }) const response = await axios.get(generateOcsUrl('apps/files_sharing/api/v1') + 'sharees', { params })
commit('setSharees', response.data.ocs.data) commit('setSharees', response.data.ocs.data)

View File

@@ -1,21 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.3.1@2feba22a005a18bf31d4c7b9bdb9252c73897476"> <files psalm-version="4.3.2@57b53ff26237074fdf5cbcb034f7da5172be4524">
<file src="lib/Activity/ActivityManager.php"> <file src="lib/Activity/ActivityManager.php">
<TypeDoesNotContainType occurrences="1"> <TypeDoesNotContainType occurrences="1">
<code>$message !== null</code> <code>$message !== null</code>
</TypeDoesNotContainType> </TypeDoesNotContainType>
<UndefinedMagicMethod occurrences="9">
<code>getArchived</code>
<code>getBoardId</code>
<code>getBoardId</code>
<code>getBoardId</code>
<code>getBoardId</code>
<code>getCardId</code>
<code>getCardId</code>
<code>getStackId</code>
<code>getTitle</code>
<code>getTitle</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Activity/DeckProvider.php"> <file src="lib/Activity/DeckProvider.php">
<InvalidScalarArgument occurrences="1"> <InvalidScalarArgument occurrences="1">
@@ -27,25 +15,6 @@
<code>Application</code> <code>Application</code>
</DuplicateClass> </DuplicateClass>
</file> </file>
<file src="lib/AppInfo/Application20.php">
<UndefinedClass occurrences="1">
<code>IBootstrap</code>
</UndefinedClass>
</file>
<file src="lib/AppInfo/ApplicationLegacy.php">
<UndefinedInterfaceMethod occurrences="2">
<code>listen</code>
<code>listen</code>
</UndefinedInterfaceMethod>
</file>
<file src="lib/Collaboration/Resources/ResourceProviderCard.php">
<UndefinedMagicMethod occurrences="4">
<code>getAcl</code>
<code>getOwner</code>
<code>getTitle</code>
<code>getTitle</code>
</UndefinedMagicMethod>
</file>
<file src="lib/Command/UserExport.php"> <file src="lib/Command/UserExport.php">
<ImplementedReturnTypeMismatch occurrences="1"> <ImplementedReturnTypeMismatch occurrences="1">
<code>void</code> <code>void</code>
@@ -89,13 +58,6 @@
<code>$parentId</code> <code>$parentId</code>
</InvalidScalarArgument> </InvalidScalarArgument>
</file> </file>
<file src="lib/Controller/PageController.php">
<MissingDependency occurrences="3">
<code>Application</code>
<code>Application</code>
<code>Application</code>
</MissingDependency>
</file>
<file src="lib/Controller/StackApiController.php"> <file src="lib/Controller/StackApiController.php">
<RedundantCondition occurrences="1"> <RedundantCondition occurrences="1">
<code>$modified !== null</code> <code>$modified !== null</code>
@@ -104,21 +66,6 @@
<code>Util</code> <code>Util</code>
</UndefinedClass> </UndefinedClass>
</file> </file>
<file src="lib/Cron/CardDescriptionActivity.php">
<UndefinedClass occurrences="1">
<code>Job</code>
</UndefinedClass>
</file>
<file src="lib/Cron/DeleteCron.php">
<UndefinedClass occurrences="1">
<code>Job</code>
</UndefinedClass>
</file>
<file src="lib/Cron/ScheduledNotifications.php">
<UndefinedClass occurrences="1">
<code>Job</code>
</UndefinedClass>
</file>
<file src="lib/DAV/Calendar.php"> <file src="lib/DAV/Calendar.php">
<UndefinedClass occurrences="1"> <UndefinedClass occurrences="1">
<code>ExternalCalendar</code> <code>ExternalCalendar</code>
@@ -140,18 +87,6 @@
<code>NotFound</code> <code>NotFound</code>
</UndefinedClass> </UndefinedClass>
</file> </file>
<file src="lib/Dashboard/DeckWidget.php">
<UndefinedClass occurrences="1">
<code>IWidget</code>
</UndefinedClass>
</file>
<file src="lib/Db/Acl.php">
<UndefinedMagicMethod occurrences="3">
<code>getPermissionEdit</code>
<code>getPermissionManage</code>
<code>getPermissionShare</code>
</UndefinedMagicMethod>
</file>
<file src="lib/Db/AclMapper.php"> <file src="lib/Db/AclMapper.php">
<ParamNameMismatch occurrences="1"> <ParamNameMismatch occurrences="1">
<code>$aclId</code> <code>$aclId</code>
@@ -161,60 +96,26 @@
<ParamNameMismatch occurrences="1"> <ParamNameMismatch occurrences="1">
<code>$cardId</code> <code>$cardId</code>
</ParamNameMismatch> </ParamNameMismatch>
<UndefinedMagicMethod occurrences="9">
<code>getParticipant</code>
<code>getParticipant</code>
<code>getParticipant</code>
<code>getParticipant</code>
<code>getParticipant</code>
<code>getParticipant</code>
<code>getType</code>
<code>getType</code>
<code>getType</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Db/AttachmentMapper.php"> <file src="lib/Db/AttachmentMapper.php">
<UndefinedMagicMethod occurrences="2">
<code>getCardId</code>
<code>getCardId</code>
</UndefinedMagicMethod>
<UndefinedVariable occurrences="1"> <UndefinedVariable occurrences="1">
<code>$query</code> <code>$query</code>
</UndefinedVariable> </UndefinedVariable>
</file> </file>
<file src="lib/Db/Board.php">
<UndefinedMagicMethod occurrences="1">
<code>getLastModified</code>
</UndefinedMagicMethod>
</file>
<file src="lib/Db/BoardMapper.php"> <file src="lib/Db/BoardMapper.php">
<ParamNameMismatch occurrences="1"> <ParamNameMismatch occurrences="1">
<code>$boardId</code> <code>$boardId</code>
</ParamNameMismatch> </ParamNameMismatch>
<UndefinedClass occurrences="1"> <UndefinedClass occurrences="2">
<code>\OCA\Circles\Api\v1\Circles</code>
<code>\OCA\Circles\Api\v1\Circles</code> <code>\OCA\Circles\Api\v1\Circles</code>
</UndefinedClass> </UndefinedClass>
<UndefinedMagicMethod occurrences="2">
<code>setAcl</code>
<code>setLabels</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Db/Card.php"> <file src="lib/Db/Card.php">
<UndefinedClass occurrences="2"> <UndefinedClass occurrences="2">
<code>VCalendar</code> <code>VCalendar</code>
<code>VCalendar</code> <code>VCalendar</code>
</UndefinedClass> </UndefinedClass>
<UndefinedMagicMethod occurrences="9">
<code>getArchived</code>
<code>getArchived</code>
<code>getDescription</code>
<code>getLabels</code>
<code>getLabels</code>
<code>getLastModified</code>
<code>getLastModified</code>
<code>getStackId</code>
<code>getTitle</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Db/CardMapper.php"> <file src="lib/Db/CardMapper.php">
<ImplicitToStringCast occurrences="1"> <ImplicitToStringCast occurrences="1">
@@ -226,21 +127,6 @@
<ParamNameMismatch occurrences="1"> <ParamNameMismatch occurrences="1">
<code>$cardId</code> <code>$cardId</code>
</ParamNameMismatch> </ParamNameMismatch>
<UndefinedMagicMethod occurrences="13">
<code>getDescription</code>
<code>getDescription</code>
<code>getDuedate</code>
<code>setCreatedAt</code>
<code>setDatabaseType</code>
<code>setDatabaseType</code>
<code>setDescription</code>
<code>setDescription</code>
<code>setLabels</code>
<code>setLastModified</code>
<code>setLastModified</code>
<code>setNotified</code>
<code>setNotified</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Db/ChangeHelper.php"> <file src="lib/Db/ChangeHelper.php">
<UndefinedThisPropertyAssignment occurrences="3"> <UndefinedThisPropertyAssignment occurrences="3">
@@ -269,69 +155,21 @@
<code>\OCA\Circles\Model\Circle</code> <code>\OCA\Circles\Model\Circle</code>
</UndefinedDocblockClass> </UndefinedDocblockClass>
</file> </file>
<file src="lib/Db/Label.php">
<UndefinedMagicMethod occurrences="1">
<code>getLastModified</code>
</UndefinedMagicMethod>
</file>
<file src="lib/Db/LabelMapper.php"> <file src="lib/Db/LabelMapper.php">
<ParamNameMismatch occurrences="1"> <ParamNameMismatch occurrences="1">
<code>$labelId</code> <code>$labelId</code>
</ParamNameMismatch> </ParamNameMismatch>
<UndefinedMagicMethod occurrences="2">
<code>setLastModified</code>
<code>setLastModified</code>
</UndefinedMagicMethod>
</file>
<file src="lib/Db/RelationalEntity.php">
<UndefinedMagicMethod occurrences="1">
<code>getETag</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Db/Stack.php"> <file src="lib/Db/Stack.php">
<UndefinedClass occurrences="2"> <UndefinedClass occurrences="2">
<code>VCalendar</code> <code>VCalendar</code>
<code>VCalendar</code> <code>VCalendar</code>
</UndefinedClass> </UndefinedClass>
<UndefinedMagicMethod occurrences="2">
<code>getLastModified</code>
<code>getTitle</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Db/StackMapper.php"> <file src="lib/Db/StackMapper.php">
<ParamNameMismatch occurrences="1"> <ParamNameMismatch occurrences="1">
<code>$stackId</code> <code>$stackId</code>
</ParamNameMismatch> </ParamNameMismatch>
<UndefinedMagicMethod occurrences="1">
<code>getBoardId</code>
</UndefinedMagicMethod>
</file>
<file src="lib/Listeners/BeforeTemplateRenderedListener.php">
<UndefinedClass occurrences="1">
<code>BeforeTemplateRenderedEvent</code>
</UndefinedClass>
</file>
<file src="lib/Migration/UnknownUsers.php">
<UndefinedMagicMethod occurrences="4">
<code>getParticipant</code>
<code>getParticipant</code>
<code>getType</code>
<code>getType</code>
</UndefinedMagicMethod>
</file>
<file src="lib/Notification/NotificationHelper.php">
<InvalidScalarArgument occurrences="1">
<code>$board-&gt;getId()</code>
</InvalidScalarArgument>
<MissingDependency occurrences="1">
<code>Application</code>
</MissingDependency>
<UndefinedMagicMethod occurrences="3">
<code>getTitle</code>
<code>getTitle</code>
<code>getTitle</code>
<code>getTitle</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Notification/Notifier.php"> <file src="lib/Notification/Notifier.php">
<RedundantCast occurrences="7"> <RedundantCast occurrences="7">
@@ -348,129 +186,18 @@
<InvalidPropertyAssignmentValue occurrences="1"> <InvalidPropertyAssignmentValue occurrences="1">
<code>[]</code> <code>[]</code>
</InvalidPropertyAssignmentValue> </InvalidPropertyAssignmentValue>
<UndefinedClass occurrences="2">
<code>IndexDocument</code>
<code>SearchTemplate</code>
</UndefinedClass>
</file>
<file src="lib/Search/BoardSearchResultEntry.php">
<UndefinedClass occurrences="1">
<code>SearchResultEntry</code>
</UndefinedClass>
</file>
<file src="lib/Search/CardSearchResultEntry.php">
<UndefinedClass occurrences="1">
<code>SearchResultEntry</code>
</UndefinedClass>
</file>
<file src="lib/Search/DeckProvider.php">
<UndefinedClass occurrences="1">
<code>IProvider</code>
</UndefinedClass>
</file> </file>
<file src="lib/Service/AssignmentService.php"> <file src="lib/Service/AssignmentService.php">
<InvalidScalarArgument occurrences="2"> <InvalidScalarArgument occurrences="2">
<code>$cardId</code> <code>$cardId</code>
<code>$cardId</code> <code>$cardId</code>
</InvalidScalarArgument> </InvalidScalarArgument>
<UndefinedMagicMethod occurrences="9">
<code>getParticipant</code>
<code>getParticipant</code>
<code>getParticipant</code>
<code>getType</code>
<code>getType</code>
<code>getType</code>
<code>setCardId</code>
<code>setParticipant</code>
<code>setType</code>
</UndefinedMagicMethod>
<UndefinedThisPropertyAssignment occurrences="1">
<code>$this-&gt;currentUser</code>
</UndefinedThisPropertyAssignment>
<UndefinedThisPropertyFetch occurrences="1">
<code>$this-&gt;currentUser</code>
</UndefinedThisPropertyFetch>
</file>
<file src="lib/Service/AttachmentService.php">
<MissingDependency occurrences="1">
<code>Application</code>
</MissingDependency>
<UndefinedMagicMethod occurrences="13">
<code>getCardId</code>
<code>getCardId</code>
<code>getCardId</code>
<code>getData</code>
<code>getType</code>
<code>getType</code>
<code>setCardId</code>
<code>setCreatedAt</code>
<code>setCreatedBy</code>
<code>setData</code>
<code>setLastModified</code>
<code>setLastModified</code>
<code>setType</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Service/BoardService.php"> <file src="lib/Service/BoardService.php">
<InvalidArgument occurrences="6">
<code>'\OCA\Deck\Board::onCreate'</code>
<code>'\OCA\Deck\Board::onDelete'</code>
<code>'\OCA\Deck\Board::onDelete'</code>
<code>'\OCA\Deck\Board::onShareEdit'</code>
<code>'\OCA\Deck\Board::onUpdate'</code>
<code>'\OCA\Deck\Board::onUpdate'</code>
</InvalidArgument>
<MissingDependency occurrences="3">
<code>Application</code>
<code>Application</code>
<code>Application</code>
</MissingDependency>
<TooManyArguments occurrences="2"> <TooManyArguments occurrences="2">
<code>findAll</code> <code>findAll</code>
<code>findAll</code> <code>findAll</code>
</TooManyArguments> </TooManyArguments>
<UndefinedMagicMethod occurrences="40">
<code>getAcl</code>
<code>getAcl</code>
<code>getAcl</code>
<code>getBoardId</code>
<code>getBoardId</code>
<code>getBoardId</code>
<code>getBoardId</code>
<code>getParticipant</code>
<code>getType</code>
<code>setBoardId</code>
<code>setBoardId</code>
<code>setBoardId</code>
<code>setBoardId</code>
<code>setColor</code>
<code>setColor</code>
<code>setColor</code>
<code>setColor</code>
<code>setColor</code>
<code>setLabels</code>
<code>setOwner</code>
<code>setOwner</code>
<code>setParticipant</code>
<code>setPermissionEdit</code>
<code>setPermissionEdit</code>
<code>setPermissionManage</code>
<code>setPermissionManage</code>
<code>setPermissionShare</code>
<code>setPermissionShare</code>
<code>setPermissions</code>
<code>setPermissions</code>
<code>setPermissions</code>
<code>setPermissions</code>
<code>setSettings</code>
<code>setTitle</code>
<code>setTitle</code>
<code>setTitle</code>
<code>setTitle</code>
<code>setTitle</code>
<code>setTitle</code>
<code>setType</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Service/CardService.php"> <file src="lib/Service/CardService.php">
<TooFewArguments occurrences="1"> <TooFewArguments occurrences="1">
@@ -479,52 +206,6 @@
<UndefinedDocblockClass occurrences="1"> <UndefinedDocblockClass occurrences="1">
<code>\OCP\AppFramework\Db\</code> <code>\OCP\AppFramework\Db\</code>
</UndefinedDocblockClass> </UndefinedDocblockClass>
<UndefinedMagicMethod occurrences="44">
<code>getArchived</code>
<code>getArchived</code>
<code>getArchived</code>
<code>getArchived</code>
<code>getArchived</code>
<code>getDescription</code>
<code>getDescription</code>
<code>getDescription</code>
<code>getDescriptionPrev</code>
<code>getDescriptionPrev</code>
<code>getLastEditor</code>
<code>getLastEditor</code>
<code>getLastEditor</code>
<code>getOrder</code>
<code>setArchived</code>
<code>setArchived</code>
<code>setArchived</code>
<code>setAssignedUsers</code>
<code>setAssignedUsers</code>
<code>setAttachmentCount</code>
<code>setAttachments</code>
<code>setCommentsUnread</code>
<code>setDeletedAt</code>
<code>setDeletedAt</code>
<code>setDescription</code>
<code>setDescription</code>
<code>setDescriptionPrev</code>
<code>setDescriptionPrev</code>
<code>setDuedate</code>
<code>setDuedate</code>
<code>setLabels</code>
<code>setLastEditor</code>
<code>setOrder</code>
<code>setOrder</code>
<code>setOwner</code>
<code>setOwner</code>
<code>setStackId</code>
<code>setStackId</code>
<code>setStackId</code>
<code>setTitle</code>
<code>setTitle</code>
<code>setTitle</code>
<code>setType</code>
<code>setType</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Service/CirclesService.php"> <file src="lib/Service/CirclesService.php">
<UndefinedClass occurrences="2"> <UndefinedClass occurrences="2">
@@ -533,13 +214,6 @@
</UndefinedClass> </UndefinedClass>
</file> </file>
<file src="lib/Service/CommentService.php"> <file src="lib/Service/CommentService.php">
<MissingDependency occurrences="5">
<code>Application</code>
<code>Application</code>
<code>Application</code>
<code>Application</code>
<code>Application</code>
</MissingDependency>
<UndefinedThisPropertyAssignment occurrences="2"> <UndefinedThisPropertyAssignment occurrences="2">
<code>$this-&gt;cardMapper</code> <code>$this-&gt;cardMapper</code>
<code>$this-&gt;permissionService</code> <code>$this-&gt;permissionService</code>
@@ -559,21 +233,8 @@
<InvalidScalarArgument occurrences="1"> <InvalidScalarArgument occurrences="1">
<code>(int)$value</code> <code>(int)$value</code>
</InvalidScalarArgument> </InvalidScalarArgument>
<MissingDependency occurrences="7">
<code>Application</code>
<code>Application</code>
<code>Application</code>
<code>Application</code>
<code>Application</code>
<code>Application</code>
<code>Application</code>
</MissingDependency>
</file> </file>
<file src="lib/Service/DefaultBoardService.php"> <file src="lib/Service/DefaultBoardService.php">
<MissingDependency occurrences="2">
<code>Application</code>
<code>Application</code>
</MissingDependency>
<TypeDoesNotContainNull occurrences="6"> <TypeDoesNotContainNull occurrences="6">
<code>$color === false || $color === null</code> <code>$color === false || $color === null</code>
<code>$color === null</code> <code>$color === null</code>
@@ -597,94 +258,17 @@
<code>is_resource($content)</code> <code>is_resource($content)</code>
<code>is_resource($content)</code> <code>is_resource($content)</code>
</RedundantCondition> </RedundantCondition>
<UndefinedMagicMethod occurrences="10">
<code>getCardId</code>
<code>getCardId</code>
<code>getCardId</code>
<code>getData</code>
<code>getData</code>
<code>setData</code>
<code>setData</code>
<code>setDeletedAt</code>
<code>setExtendedData</code>
<code>setLastModified</code>
</UndefinedMagicMethod>
</file>
<file src="lib/Service/FullTextSearchService.php">
<UndefinedClass occurrences="2">
<code>DocumentAccess</code>
<code>IndexDocument</code>
</UndefinedClass>
<UndefinedMagicMethod occurrences="4">
<code>getDescription</code>
<code>getDescription</code>
<code>getTitle</code>
<code>getTitle</code>
</UndefinedMagicMethod>
</file>
<file src="lib/Service/LabelService.php">
<UndefinedMagicMethod occurrences="4">
<code>getBoardId</code>
<code>getBoardId</code>
<code>getBoardId</code>
<code>setBoardId</code>
<code>setColor</code>
<code>setColor</code>
<code>setTitle</code>
<code>setTitle</code>
</UndefinedMagicMethod>
</file>
<file src="lib/Service/OverviewService.php">
<UndefinedMagicMethod occurrences="4">
<code>setAssignedUsers</code>
<code>setAttachmentCount</code>
<code>setCommentsUnread</code>
<code>setLabels</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Service/PermissionService.php"> <file src="lib/Service/PermissionService.php">
<UndefinedClass occurrences="2"> <UndefinedClass occurrences="3">
<code>Member</code>
<code>\OCA\Circles\Api\v1\Circles</code> <code>\OCA\Circles\Api\v1\Circles</code>
<code>\OCA\Circles\Api\v1\Circles</code> <code>\OCA\Circles\Api\v1\Circles</code>
</UndefinedClass> </UndefinedClass>
<UndefinedMagicMethod occurrences="6">
<code>getAcl</code>
<code>getParticipant</code>
<code>getParticipant</code>
<code>getParticipant</code>
<code>getParticipant</code>
<code>getType</code>
<code>getType</code>
<code>getType</code>
<code>getType</code>
<code>getType</code>
<code>getType</code>
</UndefinedMagicMethod>
</file> </file>
<file src="lib/Service/StackService.php"> <file src="lib/Service/StackService.php">
<InvalidArgument occurrences="3">
<code>'\OCA\Deck\Stack::onCreate'</code>
<code>'\OCA\Deck\Stack::onDelete'</code>
<code>'\OCA\Deck\Stack::onUpdate'</code>
</InvalidArgument>
<UndefinedClass occurrences="1"> <UndefinedClass occurrences="1">
<code>BadRquestException</code> <code>BadRquestException</code>
</UndefinedClass> </UndefinedClass>
<UndefinedMagicMethod occurrences="14">
<code>getBoardId</code>
<code>getBoardId</code>
<code>getBoardId</code>
<code>getBoardId</code>
<code>getOrder</code>
<code>setBoardId</code>
<code>setBoardId</code>
<code>setCards</code>
<code>setDeletedAt</code>
<code>setDeletedAt</code>
<code>setOrder</code>
<code>setOrder</code>
<code>setTitle</code>
<code>setTitle</code>
</UndefinedMagicMethod>
</file> </file>
</files> </files>

View File

@@ -24,6 +24,7 @@
namespace OCA\Deck\Db; namespace OCA\Deck\Db;
use OCP\IGroupManager; use OCP\IGroupManager;
use OCP\ILogger;
use OCP\IUserManager; use OCP\IUserManager;
use Test\AppFramework\Db\MapperTestUtility; use Test\AppFramework\Db\MapperTestUtility;
@@ -54,7 +55,8 @@ class AclMapperTest extends MapperTestUtility {
$this->aclMapper, $this->aclMapper,
\OC::$server->query(StackMapper::class), \OC::$server->query(StackMapper::class),
$this->userManager, $this->userManager,
$this->groupManager $this->groupManager,
$this->createMock(ILogger::class)
); );
$this->boards = [ $this->boards = [

View File

@@ -25,6 +25,7 @@ namespace OCA\Deck\Db;
use OCP\IDBConnection; use OCP\IDBConnection;
use OCP\IGroupManager; use OCP\IGroupManager;
use OCP\ILogger;
use OCP\IUserManager; use OCP\IUserManager;
use Test\AppFramework\Db\MapperTestUtility; use Test\AppFramework\Db\MapperTestUtility;
@@ -61,7 +62,8 @@ class BoardMapperTest extends MapperTestUtility {
\OC::$server->query(AclMapper::class), \OC::$server->query(AclMapper::class),
\OC::$server->query(StackMapper::class), \OC::$server->query(StackMapper::class),
$this->userManager, $this->userManager,
$this->groupManager $this->groupManager,
$this->createMock(ILogger::class)
); );
$this->aclMapper = \OC::$server->query(AclMapper::class); $this->aclMapper = \OC::$server->query(AclMapper::class);
$this->labelMapper = \OC::$server->query(LabelMapper::class); $this->labelMapper = \OC::$server->query(LabelMapper::class);

View File

@@ -130,7 +130,8 @@ class NotificationHelperTest extends \Test\TestCase {
$card = Card::fromParams([ $card = Card::fromParams([
'notified' => false, 'notified' => false,
'id' => 123, 'id' => 123,
'title' => 'MyCardTitle' 'title' => 'MyCardTitle',
'duedate' => '2020-12-24'
]); ]);
$this->cardMapper->expects($this->once()) $this->cardMapper->expects($this->once())
->method('findBoardId') ->method('findBoardId')
@@ -225,7 +226,8 @@ class NotificationHelperTest extends \Test\TestCase {
$card = Card::fromParams([ $card = Card::fromParams([
'notified' => false, 'notified' => false,
'id' => 123, 'id' => 123,
'title' => 'MyCardTitle' 'title' => 'MyCardTitle',
'duedate' => '2020-12-24'
]); ]);
$card->setAssignedUsers([ $card->setAssignedUsers([
new User($users[0]) new User($users[0])
@@ -323,7 +325,8 @@ class NotificationHelperTest extends \Test\TestCase {
$card = Card::fromParams([ $card = Card::fromParams([
'notified' => false, 'notified' => false,
'id' => 123, 'id' => 123,
'title' => 'MyCardTitle' 'title' => 'MyCardTitle',
'duedate' => '2020-12-24'
]); ]);
$card->setAssignedUsers([ $card->setAssignedUsers([
new User($users[0]) new User($users[0])
@@ -470,7 +473,7 @@ class NotificationHelperTest extends \Test\TestCase {
->with(123) ->with(123)
->willReturn($board); ->willReturn($board);
$user = $this->createMock(IUser::class); $user = $this->createMock(IUser::class);
$user->expects($this->once()) $user->expects($this->any())
->method('getUID') ->method('getUID')
->willReturn('userA'); ->willReturn('userA');
$group = $this->createMock(IGroup::class); $group = $this->createMock(IGroup::class);

View File

@@ -25,10 +25,10 @@ namespace OCA\Deck\Service;
use OCA\Deck\Db\Attachment; use OCA\Deck\Db\Attachment;
use OCA\Deck\Db\AttachmentMapper; use OCA\Deck\Db\AttachmentMapper;
use OCP\AppFramework\Http\ContentSecurityPolicy;
use OCP\AppFramework\Http\StreamResponse; use OCP\AppFramework\Http\StreamResponse;
use OCP\Files\Folder; use OCP\Files\Folder;
use OCP\Files\IAppData; use OCP\Files\IAppData;
use OCP\Files\IMimeTypeDetector;
use OCP\Files\IRootFolder; use OCP\Files\IRootFolder;
use OCP\Files\SimpleFS\ISimpleFile; use OCP\Files\SimpleFS\ISimpleFile;
use OCP\Files\SimpleFS\ISimpleFolder; use OCP\Files\SimpleFS\ISimpleFolder;
@@ -57,6 +57,8 @@ class FileServiceTest extends TestCase {
private $config; private $config;
/** @var AttachmentMapper|MockObject */ /** @var AttachmentMapper|MockObject */
private $attachmentMapper; private $attachmentMapper;
/** @var IMimeTypeDetector|MockObject */
private $mimeTypeDetector;
public function setUp(): void { public function setUp(): void {
parent::setUp(); parent::setUp();
@@ -67,7 +69,8 @@ class FileServiceTest extends TestCase {
$this->rootFolder = $this->createMock(IRootFolder::class); $this->rootFolder = $this->createMock(IRootFolder::class);
$this->config = $this->createMock(IConfig::class); $this->config = $this->createMock(IConfig::class);
$this->attachmentMapper = $this->createMock(AttachmentMapper::class); $this->attachmentMapper = $this->createMock(AttachmentMapper::class);
$this->fileService = new FileService($this->l10n, $this->appData, $this->request, $this->logger, $this->rootFolder, $this->config, $this->attachmentMapper); $this->mimeTypeDetector = $this->createMock(IMimeTypeDetector::class);
$this->fileService = new FileService($this->l10n, $this->appData, $this->request, $this->logger, $this->rootFolder, $this->config, $this->attachmentMapper, $this->mimeTypeDetector);
} }
public function mockGetFolder($cardId) { public function mockGetFolder($cardId) {
@@ -268,51 +271,13 @@ class FileServiceTest extends TestCase {
$file->expects($this->any()) $file->expects($this->any())
->method('fopen') ->method('fopen')
->willReturn('fileresource'); ->willReturn('fileresource');
$this->mimeTypeDetector->expects($this->once())
->method('getSecureMimeType')
->willReturn('image/jpeg');
$actual = $this->fileService->display($attachment); $actual = $this->fileService->display($attachment);
$expected = new StreamResponse('fileresource'); $expected = new StreamResponse('fileresource');
$expected->addHeader('Content-Type', 'image/jpeg'); $expected->addHeader('Content-Type', 'image/jpeg');
$expected->addHeader('Content-Disposition', 'inline; filename="' . rawurldecode($file->getName()) . '"'); $expected->addHeader('Content-Disposition', 'attachment; filename="' . rawurldecode($file->getName()) . '"');
$policy = new ContentSecurityPolicy();
$policy->addAllowedObjectDomain('\'self\'');
$policy->addAllowedObjectDomain('blob:');
$policy->addAllowedMediaDomain('\'self\'');
$policy->addAllowedMediaDomain('blob:');
$expected->setContentSecurityPolicy($policy);
$this->assertEquals($expected, $actual);
}
public function testDisplayPdf() {
$this->config->expects($this->once())
->method('getSystemValue')
->willReturn('123');
$appDataFolder = $this->createMock(Folder::class);
$deckAppDataFolder = $this->createMock(Folder::class);
$cardFolder = $this->createMock(Folder::class);
$this->rootFolder->expects($this->once())->method('get')->willReturn($appDataFolder);
$appDataFolder->expects($this->once())->method('get')->willReturn($deckAppDataFolder);
$deckAppDataFolder->expects($this->once())->method('get')->willReturn($cardFolder);
$attachment = $this->getAttachment();
$file = $this->createMock(\OCP\Files\File::class);
$cardFolder->expects($this->once())->method('get')->willReturn($file);
$file->expects($this->any())
->method('getMimeType')
->willReturn('application/pdf');
$file->expects($this->any())
->method('getName')
->willReturn('file1');
$file->expects($this->any())
->method('fopen')
->willReturn('fileresource');
$actual = $this->fileService->display($attachment);
$expected = new StreamResponse('fileresource');
$expected->addHeader('Content-Disposition', 'inline; filename="' . rawurldecode($file->getName()) . '"');
$expected->addHeader('Content-Type', 'application/pdf');
$policy = new ContentSecurityPolicy();
$policy->addAllowedObjectDomain('\'self\'');
$policy->addAllowedObjectDomain('blob:');
$policy->addAllowedMediaDomain('\'self\'');
$policy->addAllowedMediaDomain('blob:');
$expected->setContentSecurityPolicy($policy);
$this->assertEquals($expected, $actual); $this->assertEquals($expected, $actual);
} }