From 5577929c02c80d4d70140307c633e3e5506f5660 Mon Sep 17 00:00:00 2001 From: Swikriti Tripathi <41103328+SwikritiT@users.noreply.github.com> Date: Mon, 21 Aug 2023 17:03:13 +0545 Subject: [PATCH] Revert "Merge release2.4 to master (#458)" This reverts commit 1c6097ee3f4056833f81384bd658a0c0df906501. Signed-off-by: Swikriti Tripathi --- lib/Controller/OpenProjectAPIController.php | 7 +- lib/Listener/OpenProjectReferenceListener.php | 27 ---- .../WorkPackageReferenceProvider.php | 32 ++-- lib/Search/OpenProjectSearchProvider.php | 20 ++- lib/Service/OpenProjectAPIService.php | 29 +--- phpstan.neon | 1 - src/components/AdminSettings.vue | 41 ++--- src/components/admin/FormHeading.vue | 18 +-- src/components/icons/OpenProjectIcon.vue | 31 ---- src/components/tab/EmptyContent.vue | 20 +-- src/components/tab/SearchInput.vue | 52 ++---- src/reference.js | 19 +-- src/views/WorkPackagePickerElement.vue | 91 ----------- tests/acceptance/features/api/setup.feature | 10 +- .../features/bootstrap/FeatureContext.php | 83 ---------- tests/jest/components/AdminSettings.spec.js | 25 --- .../__snapshots__/AdminSettings.spec.js.snap | 6 +- .../__snapshots__/FormHeading.spec.js.snap | 4 +- tests/jest/components/tab/SearchInput.spec.js | 57 ------- .../WorkPackageReferenceProviderTest.php | 82 ---------- .../lib/Service/OpenProjectAPIServiceTest.php | 153 +----------------- 21 files changed, 85 insertions(+), 723 deletions(-) delete mode 100644 src/components/icons/OpenProjectIcon.vue delete mode 100644 src/views/WorkPackagePickerElement.vue delete mode 100644 tests/lib/Reference/WorkPackageReferenceProviderTest.php diff --git a/lib/Controller/OpenProjectAPIController.php b/lib/Controller/OpenProjectAPIController.php index 037899865..b7b314cd7 100644 --- a/lib/Controller/OpenProjectAPIController.php +++ b/lib/Controller/OpenProjectAPIController.php @@ -154,18 +154,17 @@ public function getNotifications(): DataResponse { * * @return DataResponse */ - public function getSearchedWorkPackages(?string $searchQuery = null, ?int $fileId = null, bool $isSmartPicker = false): DataResponse { + public function getSearchedWorkPackages(?string $searchQuery = null, ?int $fileId = null): DataResponse { if ($this->accessToken === '') { return new DataResponse('', Http::STATUS_UNAUTHORIZED); } elseif (!OpenProjectAPIService::validateURL($this->openprojectUrl)) { return new DataResponse('', Http::STATUS_BAD_REQUEST); } - // when the search is done through smart picker we don't want to check if the work package is linkable + $result = $this->openprojectAPIService->searchWorkPackage( $this->userId, $searchQuery, - $fileId, - !$isSmartPicker + $fileId ); if (!isset($result['error'])) { diff --git a/lib/Listener/OpenProjectReferenceListener.php b/lib/Listener/OpenProjectReferenceListener.php index e802197b4..b6d84eae6 100644 --- a/lib/Listener/OpenProjectReferenceListener.php +++ b/lib/Listener/OpenProjectReferenceListener.php @@ -23,36 +23,15 @@ namespace OCA\OpenProject\Listener; use OCA\OpenProject\AppInfo\Application; -use OCA\OpenProject\Service\OpenProjectAPIService; -use OCP\AppFramework\Services\IInitialState; use OCP\Collaboration\Reference\RenderReferenceEvent; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; -use OCP\IConfig; use OCP\Util; /** * @template-implements IEventListener */ class OpenProjectReferenceListener implements IEventListener { - - /** - * @var IInitialState - */ - private $initialStateService; - - /** - * @var IConfig - */ - private $config; - - public function __construct( - IInitialState $initialStateService, - IConfig $config - ) { - $this->initialStateService = $initialStateService; - $this->config = $config; - } public function handle(Event $event): void { // @phpstan-ignore-next-line - make phpstan not complain in nextcloud version other than 26 if (!$event instanceof RenderReferenceEvent) { @@ -60,11 +39,5 @@ public function handle(Event $event): void { } Util::addScript(Application::APP_ID, Application::APP_ID . '-reference'); - $this->initialStateService->provideInitialState('admin-config-status', OpenProjectAPIService::isAdminConfigOk($this->config)); - - $this->initialStateService->provideInitialState( - 'openproject-url', - $this->config->getAppValue(Application::APP_ID, 'openproject_instance_url') - ); } } diff --git a/lib/Reference/WorkPackageReferenceProvider.php b/lib/Reference/WorkPackageReferenceProvider.php index cb078eeb2..b3e26e56d 100644 --- a/lib/Reference/WorkPackageReferenceProvider.php +++ b/lib/Reference/WorkPackageReferenceProvider.php @@ -25,6 +25,7 @@ use OCA\OpenProject\Service\OpenProjectAPIService; use OCP\Collaboration\Reference\ADiscoverableReferenceProvider; +use OCP\Collaboration\Reference\ISearchableReferenceProvider; use OCP\Collaboration\Reference\Reference; use OC\Collaboration\Reference\ReferenceManager; use OCA\OpenProject\AppInfo\Application; @@ -33,7 +34,7 @@ use OCP\IL10N; use OCP\IURLGenerator; -class WorkPackageReferenceProvider extends ADiscoverableReferenceProvider { +class WorkPackageReferenceProvider extends ADiscoverableReferenceProvider implements ISearchableReferenceProvider { private const RICH_OBJECT_TYPE = Application::APP_ID . '_work_package'; // as we know we are on NC >= 26, we can use Php 8 syntax for class attributes @@ -75,6 +76,13 @@ public function getIconUrl(): string { ); } + /** + * @inheritDoc + */ + public function getSupportedSearchProviderIds(): array { + return ['openproject-search']; + } + /** * Parse a link to find a work package ID * @@ -82,23 +90,15 @@ public function getIconUrl(): string { * * @return int|null */ - public function getWorkPackageIdFromUrl(string $referenceText): ?int { - $patterns = array( - '\/wp\/([0-9]+)/', - '\/projects\/[^\/\?]+\/(?:work_packages|bcf)(?:\/details)?\/([0-9]+)/', - '\/(?:work_packages|notifications)\/details\/([0-9]+)/', - '\/work_packages\/([0-9]+)/', - '\/projects\/[^\/\?]+\/(?:boards|calendars|team_planners)\/[^\/\?]+\/details\/([0-9]+)/'); + private function getWorkPackageIdFromUrl(string $referenceText): ?int { // example links // https://community.openproject.org/projects/nextcloud-integration/work_packages/40070 - $openProjectUrl = rtrim($this->config->getAppValue(Application::APP_ID, 'openproject_instance_url'),'/'); - foreach ($patterns as $pattern) { - $patternString ='/^' . preg_quote($openProjectUrl, '/') . $pattern; - preg_match($patternString, $referenceText, $patternMatches); - if (count($patternMatches) > 1) { - return (int) $patternMatches[1]; - } + $openProjectUrl = $this->config->getAppValue(Application::APP_ID, 'openproject_instance_url'); + preg_match('/^' . preg_quote($openProjectUrl, '/') . '\/projects\/[^\/\?]+\/work_packages\/([0-9]+)/', $referenceText, $matches); + if (count($matches) > 1) { + return (int) $matches[1]; } + return null; } @@ -124,7 +124,7 @@ public function matchReference(string $referenceText): bool { * @inheritDoc */ public function resolveReference(string $referenceText): ?IReference { - if ($this->matchReference($referenceText) && OpenProjectAPIService::isAdminConfigOk($this->config)) { + if ($this->matchReference($referenceText)) { $wpId = $this->getWorkPackageIdFromUrl($referenceText); if ($wpId !== null) { $wpInfo = $this->openProjectAPIService->getWorkPackageInfo($this->userId, $wpId); diff --git a/lib/Search/OpenProjectSearchProvider.php b/lib/Search/OpenProjectSearchProvider.php index c8e16175f..e6a85957b 100644 --- a/lib/Search/OpenProjectSearchProvider.php +++ b/lib/Search/OpenProjectSearchProvider.php @@ -110,14 +110,24 @@ public function search(IUser $user, ISearchQuery $query): SearchResult { $offset = $offset ? intval($offset) : 0; $openprojectUrl = OpenProjectAPIService::sanitizeUrl($this->config->getAppValue(Application::APP_ID, 'openproject_instance_url')); $accessToken = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'token'); - $searchEnabled = $this->config->getUserValue( - $user->getUID(), - Application::APP_ID, 'search_enabled', - $this->config->getAppValue(Application::APP_ID, 'default_enable_unified_search', '0')) === '1'; - if ($accessToken === '' || !$searchEnabled) { + + if ($accessToken === '') { return SearchResult::paginated($this->getName(), [], 0); } + $routeFrom = $query->getRoute(); + $requestedFromSmartPicker = $routeFrom === '' || $routeFrom === 'smart-picker'; + + if (!$requestedFromSmartPicker) { + $searchEnabled = $this->config->getUserValue( + $user->getUID(), + Application::APP_ID, 'search_enabled', + $this->config->getAppValue(Application::APP_ID, 'default_enable_unified_search', '0')) === '1'; + if (!$searchEnabled) { + return SearchResult::paginated($this->getName(), [], 0); + } + } + $searchResults = $this->service->searchWorkPackage($user->getUID(), $term, null, false); $searchResults = array_slice($searchResults, $offset, $limit); diff --git a/lib/Service/OpenProjectAPIService.php b/lib/Service/OpenProjectAPIService.php index 04e957172..47a748fb2 100644 --- a/lib/Service/OpenProjectAPIService.php +++ b/lib/Service/OpenProjectAPIService.php @@ -1129,12 +1129,8 @@ public function generateAppPasswordTokenForUser(): string { */ public function deleteAppPassword(): void { if ($this->hasAppPassword()) { - $tokens = $this->tokenProvider->getTokenByUser(Application::OPEN_PROJECT_ENTITIES_NAME); - foreach ($tokens as $token) { - if ($token->getName() === Application::OPEN_PROJECT_ENTITIES_NAME) { - $this->tokenProvider->invalidateTokenById(Application::OPEN_PROJECT_ENTITIES_NAME, $token->getId()); - } - } + $tokenId = $this->tokenProvider->getTokenByUser(Application::OPEN_PROJECT_ENTITIES_NAME)[0]->getId(); + $this->tokenProvider->invalidateTokenById(Application::OPEN_PROJECT_ENTITIES_NAME, $tokenId); } } @@ -1144,13 +1140,7 @@ public function deleteAppPassword(): void { * @return bool */ public function hasAppPassword(): bool { - $tokens = $this->tokenProvider->getTokenByUser(Application::OPEN_PROJECT_ENTITIES_NAME); - foreach ($tokens as $token) { - if ($token->getName() === Application::OPEN_PROJECT_ENTITIES_NAME) { - return true; - } - } - return false; + return sizeof($this->tokenProvider->getTokenByUser(Application::OPEN_PROJECT_ENTITIES_NAME)) === 1; } /** @@ -1161,14 +1151,11 @@ public function hasAppPassword(): bool { */ public function getWorkPackageInfo(string $userId, int $wpId): array { $result[] = null; - $accessToken = $this->config->getUserValue($userId, Application::APP_ID, 'token'); - if ($accessToken) { - $searchResult = $this->searchWorkPackage($userId, null, null, false, $wpId); - $result['title'] = $this->getSubline($searchResult[0]); - $result['description'] = $this->getMainText($searchResult[0]); - $result['imageUrl'] = $this->getOpenProjectUserAvatarUrl($searchResult[0]); - $result['entry'] = $searchResult[0]; - } + $searchResult = $this->searchWorkPackage($userId, null, null, false, $wpId); + $result['title'] = $this->getSubline($searchResult[0]); + $result['description'] = $this->getMainText($searchResult[0]); + $result['imageUrl'] = $this->getOpenProjectUserAvatarUrl($searchResult[0]); + $result['entry'] = $searchResult[0]; return $result; } diff --git a/phpstan.neon b/phpstan.neon index ada9c13d0..b6fc32062 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,4 +9,3 @@ parameters: reportUnmatchedIgnoredErrors: false excludePaths: - './lib/Reference/WorkPackageReferenceProvider.php' - - './tests/lib/Reference/WorkPackageReferenceProviderTest.php' diff --git a/src/components/AdminSettings.vue b/src/components/AdminSettings.vue index 428a8bce5..6421bd0ee 100644 --- a/src/components/AdminSettings.vue +++ b/src/components/AdminSettings.vue @@ -4,9 +4,7 @@
- + :is-complete="isServerHostFormComplete" /> + :is-disabled="isOPOAuthFormInDisableMode" />
+ :is-disabled="isNcOAuthFormInDisableMode" />
-
- - - {{ t('integration_openproject', 'Create Nextcloud OAuth values') }} - -
- Automatically managed folders: {{ opUserAppPassword ? t('integration_openproject', 'Active') : t('integration_openproject', 'Inactive') }} + Automatic managed folders: {{ opUserAppPassword ? t('integration_openproject', 'Active') : t('integration_openproject', 'Inactive') }}
+ :is-disabled="isOPUserAppPasswordInDisableMode" />
-
+
{{ index }}
- - - - - - - - - diff --git a/src/components/tab/EmptyContent.vue b/src/components/tab/EmptyContent.vue index 621ab5361..0ad99eb51 100644 --- a/src/components/tab/EmptyContent.vue +++ b/src/components/tab/EmptyContent.vue @@ -3,11 +3,10 @@
- - +
-
+
{{ emptyContentTitleMessage }}
@@ -26,7 +25,6 @@ import LinkPlusIcon from 'vue-material-design-icons/LinkPlus.vue' import LinkOffIcon from 'vue-material-design-icons/LinkOff.vue' import CheckIcon from 'vue-material-design-icons/Check.vue' -import OpenProjectIcon from '../icons/OpenProjectIcon.vue' import { generateUrl } from '@nextcloud/router' import { translate as t } from '@nextcloud/l10n' import OAuthConnectButton from '../OAuthConnectButton.vue' @@ -34,7 +32,7 @@ import { STATE } from '../../utils.js' export default { name: 'EmptyContent', - components: { OAuthConnectButton, LinkPlusIcon, LinkOffIcon, CheckIcon, OpenProjectIcon }, + components: { OAuthConnectButton, LinkPlusIcon, LinkOffIcon, CheckIcon }, props: { state: { type: String, @@ -59,10 +57,6 @@ export default { type: Boolean, default: false, }, - isSmartPicker: { - type: Boolean, - default: false, - }, }, data() { return { @@ -115,11 +109,9 @@ export default { display: flex; align-items: center; justify-content: center; - &--openproject { - margin: 90px; - display: block; - align-items: center; - justify-content: center; + img { + height: 50px; + width: 50px; } } &--message { diff --git a/src/components/tab/SearchInput.vue b/src/components/tab/SearchInput.vue index 7c9570ead..c486dc2fd 100644 --- a/src/components/tab/SearchInput.vue +++ b/src/components/tab/SearchInput.vue @@ -28,7 +28,6 @@ - - diff --git a/tests/acceptance/features/api/setup.feature b/tests/acceptance/features/api/setup.feature index 68d543be6..24d14f461 100644 --- a/tests/acceptance/features/api/setup.feature +++ b/tests/acceptance/features/api/setup.feature @@ -538,9 +538,10 @@ Feature: setup the integration through an API And groupfolder "OpenProject" should be managed by the user "OpenProject" # the next step is only for the tests, because that user has a random password Given the administrator has changed the password of "OpenProject" to the default testing password - And user "OpenProject" should have a folder called "OpenProject" + Then user "OpenProject" should have a folder called "OpenProject" + # folders inside the OpenProject folder can only be deleted/renamed by the OpenProject user - And user "Carol" has been created + Given user "Carol" has been created And user "Carol" has been added to the group "OpenProject" And user "OpenProject" has created folder "/OpenProject/project-abc" Then user "Carol" should have a folder called "OpenProject/project-abc" @@ -634,12 +635,9 @@ Feature: setup the integration through an API When user "OpenProject" sends a "PROPFIND" request to "/remote.php/webdav" using current app password Then the HTTP status code should be "207" - # this is to provide test coverage for issues like this - # https://community.openproject.org/projects/nextcloud-integration/work_packages/49621 - When a new browser session for "Openproject" starts # but other values can be updated by sending a PATCH request # also we can replace old app password by sending PATCH request to get new user app password - And the administrator sends a PATCH request to the "setup" endpoint with this data: + When the administrator sends a PATCH request to the "setup" endpoint with this data: """ { "values" : { diff --git a/tests/acceptance/features/bootstrap/FeatureContext.php b/tests/acceptance/features/bootstrap/FeatureContext.php index 56d8bb9a0..ae07a4cad 100644 --- a/tests/acceptance/features/bootstrap/FeatureContext.php +++ b/tests/acceptance/features/bootstrap/FeatureContext.php @@ -8,7 +8,6 @@ use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Psr7\Request; -use GuzzleHttp\Cookie\CookieJar; use PHPUnit\Framework\Assert; use Psr\Http\Message\ResponseInterface; @@ -40,9 +39,6 @@ class FeatureContext implements Context { private ?ResponseInterface $response = null; - private CookieJar $cookieJar; - private string $requestToken; - public function getAdminUsername(): string { return $this->adminUsername; } @@ -59,20 +55,6 @@ public function getBaseUrl(): string { return $this->baseUrl; } - /** - * @return string - */ - public function getRequestToken():string { - return $this->requestToken; - } - - /** - * @return CookieJar - */ - public function getCookieJar():CookieJar { - return $this->cookieJar; - } - /** * @return ResponseInterface|null */ @@ -101,7 +83,6 @@ public function __construct( $this->adminUsername = $adminUsername; $this->adminPassword = $adminPassword; $this->regularUserPassword = $regularUserPassword; - $this->cookieJar = new CookieJar(); } /** @@ -928,70 +909,6 @@ public function theContentOfFileAtForUserShouldBe( Assert::assertSame($content, $this->response->getBody()->getContents()); } - /** - * @When a new browser session for :user starts - * - * @param string $user - * - * @return void - */ - public function aNewBrowserSessionForUserStarts(string $user):void { - $loginUrl = $this->getBaseUrl() . '/index.php/login'; - $options['cookies'] = $this->getCookieJar(); - // Request a new session and extract CSRF token - $this->setResponse( - $this->sendHttpRequest( - $loginUrl, - null, - null, - 'GET', - null, - null, - $options - ) - ); - $this->theHttpStatusCodeShouldBe(200); - $this->extractRequestTokenFromResponse($this->getResponse()); - - // Login and extract new token - $body = [ - 'user' => $user, - 'password' => $this->getRegularUserPassword(), - 'requesttoken' => $this->getRequestToken() - ]; - $options['cookies'] = $this->getCookieJar(); - $this->setResponse( - $this->sendHttpRequest( - $loginUrl, - null, - null, - 'POST', - null, - $body, - $options - ) - ); - $this->theHttpStatusCodeShouldBe(200); - $this->extractRequestTokenFromResponse($this->getResponse()); - } - - /** - * @param ResponseInterface $response - * - * @return void - */ - public function extractRequestTokenFromResponse(ResponseInterface $response):void { - $this->requestToken = \substr( - \preg_replace( - '/(.*)data-requesttoken="(.*)">(.*)/sm', - '\2', - $response->getBody()->getContents() - ), - 0, - 89 - ); - } - /** * @param string|null $username * @param string|null $password diff --git a/tests/jest/components/AdminSettings.spec.js b/tests/jest/components/AdminSettings.spec.js index a7168be9a..cf0292d70 100644 --- a/tests/jest/components/AdminSettings.spec.js +++ b/tests/jest/components/AdminSettings.spec.js @@ -146,7 +146,6 @@ describe('AdminSettings.vue', () => { openproject_client_id: 'abcd', openproject_client_secret: 'abcdefgh', nc_oauth_client: null, - fresh_project_folder_setup: true, }, { server: F_MODES.VIEW, @@ -746,30 +745,6 @@ describe('AdminSettings.vue', () => { }) }) }) - describe('recreate button', () => { - it('should be displayed if nextcloud oauth credentials is empty and everything is set', async () => { - const wrapper = getMountedWrapper({ - state: { - openproject_instance_url: 'http://openproject.com', - openproject_client_id: 'op-client-id', - openproject_client_secret: 'op-client-secret', - nc_oauth_client: null, - }, - formMode: { - projectFolderSetUp: F_MODES.VIEW, - }, - showDefaultManagedProjectFolders: true, - isFormCompleted: { - projectFolderSetUp: true, - }, - - }) - const resetButton = wrapper.find(selectors.resetNcOAuthFormButton) - expect(resetButton.isVisible()).toBe(true) - expect(resetButton.text()).toBe('Create Nextcloud OAuth values') - wrapper.destroy() - }) - }) describe('edit mode', () => { it('should show the form and hide the field values', async () => { const wrapper = getWrapper({ diff --git a/tests/jest/components/__snapshots__/AdminSettings.spec.js.snap b/tests/jest/components/__snapshots__/AdminSettings.spec.js.snap index d34dde95b..0aaebe1c1 100644 --- a/tests/jest/components/__snapshots__/AdminSettings.spec.js.snap +++ b/tests/jest/components/__snapshots__/AdminSettings.spec.js.snap @@ -12,7 +12,6 @@ exports[`AdminSettings.vue Nextcloud OAuth values form edit mode should show the
-
`; @@ -28,14 +27,13 @@ exports[`AdminSettings.vue Nextcloud OAuth values form view mode with complete v
-
`; exports[`AdminSettings.vue OpenProject OAuth values form edit mode should show the form and hide the field values 1`] = `
-
+
2
@@ -105,7 +103,7 @@ exports[`AdminSettings.vue Project folders form (Project Folder Setup) view mode
-
Automatically managed folders: Inactive +
Automatic managed folders: Inactive
diff --git a/tests/jest/components/admin/__snapshots__/FormHeading.spec.js.snap b/tests/jest/components/admin/__snapshots__/FormHeading.spec.js.snap index 0ef68f125..d49944d77 100644 --- a/tests/jest/components/admin/__snapshots__/FormHeading.spec.js.snap +++ b/tests/jest/components/admin/__snapshots__/FormHeading.spec.js.snap @@ -2,7 +2,7 @@ exports[`FormHeading.vue is complete prop should hide the checkmark icon and show the index if not complete 1`] = `
-
+
1
@@ -22,7 +22,7 @@ exports[`FormHeading.vue is complete prop should show checkmark icon, add green exports[`FormHeading.vue is disabled prop should add disabled class to the form heading 1`] = `
-
+
1
diff --git a/tests/jest/components/tab/SearchInput.spec.js b/tests/jest/components/tab/SearchInput.spec.js index cd99ddadb..13afea1fa 100644 --- a/tests/jest/components/tab/SearchInput.spec.js +++ b/tests/jest/components/tab/SearchInput.spec.js @@ -9,7 +9,6 @@ import workPackagesSearchResponseNoAssignee from '../../fixtures/workPackagesSea import workPackageSearchReqResponse from '../../fixtures/workPackageSearchReqResponse.json' import workPackageObjectsInSearchResults from '../../fixtures/workPackageObjectsInSearchResults.json' import { STATE } from '../../../../src/utils.js' -import * as initialState from '@nextcloud/initial-state' jest.mock('@nextcloud/axios') jest.mock('@nextcloud/dialogs') @@ -24,13 +23,6 @@ jest.mock('lodash/debounce', () => }) ) -// eslint-disable-next-line no-import-assign,import/namespace -initialState.loadState = jest.fn(() => { - return { - openproject_instance_url: null, - } -}) - global.t = (app, text) => text const localVue = createLocalVue() @@ -151,7 +143,6 @@ describe('SearchInput.vue', () => { { params: { searchQuery: 'orga', - isSmartPicker: false, }, }, ) @@ -496,55 +487,7 @@ describe('SearchInput.vue', () => { }) }) }) - - describe('search with smartpicker', () => { - let axiosGetSpy - beforeEach(async () => { - axiosGetSpy = jest.spyOn(axios, 'get') - .mockImplementationOnce(() => Promise.resolve({ - status: 200, - data: [], - })) - wrapper = mountSearchInput() - const inputField = wrapper.find(inputSelector) - await inputField.setValue('orga') - await wrapper.setData({ - searchResults: [{ - id: 999, - projectId: 1, - }], - openprojectUrl: 'https://openproject.com', - }) - await localVue.nextTick() - await wrapper.setProps({ - isSmartPicker: true, - }) - await localVue.nextTick() - }) - afterEach(() => { - axiosGetSpy.mockRestore() - }) - it('should emit an action', async () => { - const ncSelectItem = wrapper.find(firstWorkPackageSelector) - await ncSelectItem.trigger('click') - const savedEvent = wrapper.emitted('submit') - expect(savedEvent).toHaveLength(1) - expect(savedEvent[0][0]).toEqual('https://openproject.com/wp/999') - }) - - it('should not send a request to link file to workpackage', async () => { - const postSpy = jest.spyOn(axios, 'post') - .mockImplementationOnce(() => Promise.resolve({ - status: 200, - })) - const ncSelectItem = wrapper.find(firstWorkPackageSelector) - await ncSelectItem.trigger('click') - expect(postSpy).not.toBeCalled() - postSpy.mockRestore() - }) - }) }) - function mountSearchInput(fileInfo = {}, linkedWorkPackages = [], data = {}) { return mount(SearchInput, { localVue, diff --git a/tests/lib/Reference/WorkPackageReferenceProviderTest.php b/tests/lib/Reference/WorkPackageReferenceProviderTest.php deleted file mode 100644 index ff9424287..000000000 --- a/tests/lib/Reference/WorkPackageReferenceProviderTest.php +++ /dev/null @@ -1,82 +0,0 @@ - - * - * @author Swikriti Tripathi - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -namespace OCA\OpenProject\Reference; - -use OC\Collaboration\Reference\ReferenceManager; -use OCA\OpenProject\AppInfo\Application; -use OCA\OpenProject\Service\OpenProjectAPIService; -use OCP\IConfig; -use OCP\IL10N; -use OCP\IURLGenerator; -use PHPUnit\Framework\TestCase; -use OC_Util; - -class WorkPackageReferenceProviderTest extends TestCase { - protected function setUp(): void { - if (version_compare(OC_Util::getVersionString(), '26') < 0) { - $this->markTestSkipped('WorkPackageReferenceProvider is only available from nextcloud 26 so skip the tests on versions below'); - } - } - - /** - * @return array - */ - public function getWorkPackageIdFromUrlDataProvider() { - return[ - ['https://openproject.org/projects/123/work_packages/1111'], - ['https://openproject.org/wp/1111'], - ['https://openproject.org/projects/123/work_packages/details/1111'], - ['https://openproject.org/work_packages/details/1111'], - ['https://openproject.org/work_packages/1111'], - ['https://openproject.org/work_packages/details/1111/overview'], - ['https://openproject.org/projects/wielands-playground/boards/290/details/1111/overview'], - ['https://openproject.org/projects/wielands-playground/calendars/new/details/1111/overview?cdate=2023-08-01&cview=dayGridMonth'], - ['https://openproject.org/projects/wielands-playground/calendars/519/details/1111/overview?cdate=2023-08-01&cview=dayGridMonth'], - ['https://openproject.org/projects/blabla/bcf/details/1111/overview?'], - ['https://openproject.org/notifications/details/1111/activity'], - ['https://openproject.org/projects/openproject/team_planners/12454/details/1111/overview?cdate=2023-08-14&cview=resourceTimelineWorkWeek'] - ]; - } - /** - * @dataProvider getWorkPackageIdFromUrlDataProvider - * @param string $refrenceText - * @return void - */ - public function testGetWorkPackageIdFromUrl(string $refrenceText) { - $configMock = $this->getMockBuilder(IConfig::class)->getMock(); - $configMock->method('getAppValue')->with(Application::APP_ID, 'openproject_instance_url') - ->willReturn("https://openproject.org"); - $refrenceProvider = new WorkPackageReferenceProvider( - $configMock, - $this->createMock(IL10N::class), - $this->createMock(IURLGenerator::class), - $this->createMock(ReferenceManager::class), - $this->createMock(OpenProjectAPIService::class), - 'testUser' - ); - $result = $refrenceProvider->getWorkPackageIdFromUrl($refrenceText); - - $this->assertSame(1111, $result); - } -} diff --git a/tests/lib/Service/OpenProjectAPIServiceTest.php b/tests/lib/Service/OpenProjectAPIServiceTest.php index a18ae2e6b..113c01888 100644 --- a/tests/lib/Service/OpenProjectAPIServiceTest.php +++ b/tests/lib/Service/OpenProjectAPIServiceTest.php @@ -400,7 +400,6 @@ private function getOpenProjectAPIService( * @param ISubAdmin|null $subAdminManagerMock * @param ISecureRandom|null $iSecureRandomMock * @param IConfig|null $configMock - * @param IProvider|null $tokenProviderMock * @return OpenProjectAPIService|MockObject */ private function getServiceMock( @@ -412,8 +411,7 @@ private function getServiceMock( $appManagerMock = null, $subAdminManagerMock = null, $iSecureRandomMock = null, - $configMock = null, - $tokenProviderMock = null + $configMock = null ): OpenProjectAPIService { $onlyMethods[] = 'getBaseUrl'; if ($rootMock === null) { @@ -440,9 +438,6 @@ private function getServiceMock( if ($configMock === null) { $configMock = $this->createMock(IConfig::class); } - if ($tokenProviderMock === null) { - $tokenProviderMock = $this->createMock(IProvider::class); - } $mock = $this->getMockBuilder(OpenProjectAPIService::class) ->setConstructorArgs( [ @@ -459,7 +454,7 @@ private function getServiceMock( $groupManagerMock, $appManagerMock, $this->createMock(IDBConnection::class), - $tokenProviderMock, + $this->createMock(IProvider::class), $iSecureRandomMock, $this->createMock(IEventDispatcher::class), $subAdminManagerMock, @@ -1744,150 +1739,6 @@ public function testIsSystemReadyForGroupFolderSetUpUserOrGroupExistsException( $service->isSystemReadyForProjectFolderSetUp(); } - public function testProjectFolderHasAppPassword(): void { - $tokenProviderMock = $this->getMockBuilder(IProvider::class)->disableOriginalConstructor() - ->getMock(); - $tokenMock = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock - ->method('getName') - ->willReturn('OpenProject'); - $tokenProviderMock - ->method('getTokenByUser') - ->with(Application::OPEN_PROJECT_ENTITIES_NAME) - ->willReturn([$tokenMock]); - $service = $this->getServiceMock([], - null, - null, - null, - null, - null, - null, - null, - null, - $tokenProviderMock); - $this->assertTrue($service->hasAppPassword()); - } - - public function testProjectFolderHasMultipleAppPassword(): void { - $tokenProviderMock = $this->getMockBuilder(IProvider::class)->disableOriginalConstructor() - ->getMock(); - $tokenMock1 = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock1 - ->method('getName') - ->willReturn('session'); - $tokenMock2 = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock2 - ->method('getName') - ->willReturn('test'); - $tokenMock3 = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock3 - ->method('getName') - ->willReturn('new-token'); - $tokenMock4 = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock4 - ->method('getName') - ->willReturn('OpenProject'); - $tokenProviderMock - ->method('getTokenByUser') - ->with(Application::OPEN_PROJECT_ENTITIES_NAME) - ->willReturn([$tokenMock1,$tokenMock2,$tokenMock3,$tokenMock4]); - $service = $this->getServiceMock([], - null, - null, - null, - null, - null, - null, - null, - null, - $tokenProviderMock); - $this->assertTrue($service->hasAppPassword()); - } - - public function testProjectFolderHasAppPasswordNegativeCondition(): void { - $tokenProviderMock = $this->getMockBuilder(IProvider::class)->disableOriginalConstructor() - ->getMock(); - $tokenMock = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock - ->method('getName') - ->willReturn('session'); - $tokenProviderMock - ->method('getTokenByUser') - ->with(Application::OPEN_PROJECT_ENTITIES_NAME) - ->willReturn([$tokenMock]); - $service = $this->getServiceMock([], - null, - null, - null, - null, - null, - null, - null, - null, - $tokenProviderMock); - $this->assertFalse($service->hasAppPassword()); - } - - public function testProjectFolderDeleteAppPassword(): void { - $tokenProviderMock = $this->getMockBuilder(IProvider::class)->disableOriginalConstructor() - ->getMock(); - $tokenMock1 = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock1 - ->method('getName') - ->willReturn('session'); - $tokenMock1 - ->method('getId') - ->willReturn(1); - $tokenMock2 = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock2 - ->method('getName') - ->willReturn('test'); - $tokenMock2 - ->method('getId') - ->willReturn(2); - $tokenMock3 = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock3 - ->method('getName') - ->willReturn('new-token'); - $tokenMock3 - ->method('getId') - ->willReturn(3); - $tokenMock4 = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock4 - ->method('getName') - ->willReturn('OpenProject'); - $tokenMock4 - ->method('getId') - ->willReturn(4); - $tokenMock5 = $this->getMockBuilder(IToken::class)->getMock(); - $tokenMock5 - ->method('getName') - ->willReturn('OpenProject'); - $tokenMock5 - ->method('getId') - ->willReturn(5); - $tokenProviderMock - ->method('getTokenByUser') - ->with(Application::OPEN_PROJECT_ENTITIES_NAME) - ->willReturn([$tokenMock1,$tokenMock2,$tokenMock3,$tokenMock4,$tokenMock5]); - $service = $this->getServiceMock(['hasAppPassword'], - null, - null, - null, - null, - null, - null, - null, - null, - $tokenProviderMock) - ; - $service->method('hasAppPassword')->willReturn(true); - $tokenProviderMock->expects($this->exactly(2)) - ->method('invalidateTokenById') - ->withConsecutive([Application::OPEN_PROJECT_ENTITIES_NAME, 4], [Application::OPEN_PROJECT_ENTITIES_NAME, 5]); - $service->deleteAppPassword(); - } - public function testLinkWorkPackageToFilePact(): void { $consumerRequest = new ConsumerRequest(); $consumerRequest