From ca59616a147fcb7d3497564e7f7b424f606e9f56 Mon Sep 17 00:00:00 2001 From: Jhon Date: Mon, 2 Dec 2024 13:58:17 -0400 Subject: [PATCH 01/23] Adds integration test - Fullfillment of citation field Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- cypress/tests/Test3_citationField.cy.js | 105 ++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 cypress/tests/Test3_citationField.cy.js diff --git a/cypress/tests/Test3_citationField.cy.js b/cypress/tests/Test3_citationField.cy.js new file mode 100644 index 0000000..360317a --- /dev/null +++ b/cypress/tests/Test3_citationField.cy.js @@ -0,0 +1,105 @@ +import '../support/commands.js'; + +function beginSubmission(submissionData) { + cy.get('input[name="locale"][value="en"]').click(); + cy.setTinyMceContent('startSubmission-title-control', submissionData.title); + + cy.get('input[name="submissionRequirements"]').check(); + cy.get('input[name="privacyConsent"]').check(); + cy.contains('button', 'Begin Submission').click(); +} + +function detailsStep(submissionData) { + cy.setTinyMceContent('titleAbstract-abstract-control-en', submissionData.abstract); + submissionData.keywords.forEach(keyword => { + cy.get('#titleAbstract-keywords-control-en').type(keyword, {delay: 0}); + cy.wait(500); + cy.get('#titleAbstract-keywords-control-en').type('{enter}', {delay: 0}); + }); + cy.contains('button', 'Continue').click(); +} + +function contributorsStep(submissionData) { + submissionData.contributors.forEach(authorData => { + cy.contains('button', 'Add Contributor').click(); + cy.get('input[name="givenName-en"]').type(authorData.given, {delay: 0}); + cy.get('input[name="familyName-en"]').type(authorData.family, {delay: 0}); + cy.get('input[name="email"]').type(authorData.email, {delay: 0}); + cy.get('select[name="country"]').select(authorData.country); + + cy.get('.modal__panel:contains("Add Contributor")').find('button').contains('Save').click(); + cy.waitJQuery(); + }); + + cy.contains('button', 'Continue').click(); +} + +describe('SciELO Translations Fields - Citation field features', function () { + let submissionData; + + before(function () { + submissionData = { + title: "Voodoo Child", + abstract: 'Great guitar solos', + keywords: ['guitar'], + fakeOriginalDoi: '10.4567/OriginalDoiTranslated', + realOriginalDoi: '10.1590/0037-8682-0167-2020', + originalDoiCitation: 'Croda, J., Oliveira, W. K. de ., Frutuoso, R. L. ., Mandetta, L. H. ., \ + Baia-da-Silva, D. C. ., Brito-Sousa, J. D. ., Monteiro, W. M. ., & Lacerda, M. V. G. . (2020). \ + COVID-19 in Brazil: advantages of a socialized unified health system and preparation to contain cases. \ + In SciELO Preprints. https://doi.org/10.1590/0037-8682-0167-2020 (Original work published 2020)', + contributors: [ + { + 'given': 'Jimi', + 'family': 'Hendrix', + 'email': 'jimi.hendrix@outlook.com', + 'country': 'United States' + } + ], + files: [ + { + 'file': 'dummy.pdf', + 'fileName': 'dummy.pdf', + 'mimeType': 'application/pdf', + 'genre': 'Preprint Text' + } + ] + } + }); + + it('Citation field is fullfilled when a deposited original DOI is informed', function() { + cy.login('ckwantes', null, 'publicknowledge'); + cy.get('div#myQueue a:contains("New Submission")').click(); + + beginSubmission(submissionData); + + cy.contains('legend', 'Original document citation'); + cy.contains('Descrição do campo da citação'); + + detailsStep(submissionData); + cy.addSubmissionGalleys(submissionData.files); + cy.contains('button', 'Continue').click(); + contributorsStep(submissionData); + cy.contains('button', 'Continue').click(); + + cy.wait(1000); + cy.contains('h4', 'Original document citation'); + cy.contains('You must inform the citation of the original document'); + cy.contains('button', 'Submit').should('be.disabled'); + + cy.contains('.pkpSteps__step__label', 'Details').click(); + cy.get('input[name="originalDocumentHasDoi"][value="1"]').check(); + cy.get('input[name="originalDocumentDoi"]').type(submissionData.realOriginalDoi, {delay: 0}); + cy.get('input[name="originalDocumentCitation"]').should('have.value', submissionData.originalDoiCitation); + + Cypress._.times(4, () => { + cy.contains('button', 'Continue').click(); + }); + + cy.contains('The original document has a DOI'); + cy.contains(submissionData.realOriginalDoi); + cy.contains(submissionData.originalDoiCitation); + + cy.contains('button', 'Submit').should('be.enabled'); + }); +}); \ No newline at end of file From 879e8c0cd1f61ad16ba6f2d418a17abfc427356a Mon Sep 17 00:00:00 2001 From: Jhon Date: Mon, 2 Dec 2024 16:52:16 -0400 Subject: [PATCH 02/23] Changes purpose of integration test Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- ...eld.cy.js => Test3_originalCitation.cy.js} | 37 ++++++------------- 1 file changed, 12 insertions(+), 25 deletions(-) rename cypress/tests/{Test3_citationField.cy.js => Test3_originalCitation.cy.js} (74%) diff --git a/cypress/tests/Test3_citationField.cy.js b/cypress/tests/Test3_originalCitation.cy.js similarity index 74% rename from cypress/tests/Test3_citationField.cy.js rename to cypress/tests/Test3_originalCitation.cy.js index 360317a..3ccdbd3 100644 --- a/cypress/tests/Test3_citationField.cy.js +++ b/cypress/tests/Test3_originalCitation.cy.js @@ -34,7 +34,7 @@ function contributorsStep(submissionData) { cy.contains('button', 'Continue').click(); } -describe('SciELO Translations Fields - Citation field features', function () { +describe('SciELO Translations Fields - Original document citation features', function () { let submissionData; before(function () { @@ -42,8 +42,7 @@ describe('SciELO Translations Fields - Citation field features', function () { title: "Voodoo Child", abstract: 'Great guitar solos', keywords: ['guitar'], - fakeOriginalDoi: '10.4567/OriginalDoiTranslated', - realOriginalDoi: '10.1590/0037-8682-0167-2020', + originalDoi: '10.1590/0037-8682-0167-2020', originalDoiCitation: 'Croda, J., Oliveira, W. K. de ., Frutuoso, R. L. ., Mandetta, L. H. ., \ Baia-da-Silva, D. C. ., Brito-Sousa, J. D. ., Monteiro, W. M. ., & Lacerda, M. V. G. . (2020). \ COVID-19 in Brazil: advantages of a socialized unified health system and preparation to contain cases. \ @@ -67,39 +66,27 @@ describe('SciELO Translations Fields - Citation field features', function () { } }); - it('Citation field is fullfilled when a deposited original DOI is informed', function() { + it('Creates a new submission with a deposited original DOI', function() { cy.login('ckwantes', null, 'publicknowledge'); cy.get('div#myQueue a:contains("New Submission")').click(); beginSubmission(submissionData); - - cy.contains('legend', 'Original document citation'); - cy.contains('Descrição do campo da citação'); - + cy.get('input[name="originalDocumentHasDoi"][value="1"]').check(); + cy.get('input[name="originalDocumentDoi"]').type(submissionData.originalDoi, {delay: 0}); detailsStep(submissionData); cy.addSubmissionGalleys(submissionData.files); cy.contains('button', 'Continue').click(); contributorsStep(submissionData); cy.contains('button', 'Continue').click(); - - cy.wait(1000); - cy.contains('h4', 'Original document citation'); - cy.contains('You must inform the citation of the original document'); - cy.contains('button', 'Submit').should('be.disabled'); - - cy.contains('.pkpSteps__step__label', 'Details').click(); - cy.get('input[name="originalDocumentHasDoi"][value="1"]').check(); - cy.get('input[name="originalDocumentDoi"]').type(submissionData.realOriginalDoi, {delay: 0}); - cy.get('input[name="originalDocumentCitation"]').should('have.value', submissionData.originalDoiCitation); - Cypress._.times(4, () => { - cy.contains('button', 'Continue').click(); - }); - cy.contains('The original document has a DOI'); - cy.contains(submissionData.realOriginalDoi); - cy.contains(submissionData.originalDoiCitation); + cy.contains(submissionData.originalDoi); - cy.contains('button', 'Submit').should('be.enabled'); + cy.contains('button', 'Submit').click(); + cy.get('.modal__panel:visible').within(() => { + cy.contains('button', 'Submit').click(); + }); + cy.waitJQuery(); + cy.contains('h1', 'Submission complete'); }); }); \ No newline at end of file From b897e3eeb00520043568500a8d90ead08dd50385 Mon Sep 17 00:00:00 2001 From: Jhon Date: Mon, 2 Dec 2024 17:09:07 -0400 Subject: [PATCH 03/23] Adds integration test - Check original document citation on workflow Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- cypress/tests/Test3_originalCitation.cy.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cypress/tests/Test3_originalCitation.cy.js b/cypress/tests/Test3_originalCitation.cy.js index 3ccdbd3..f749be2 100644 --- a/cypress/tests/Test3_originalCitation.cy.js +++ b/cypress/tests/Test3_originalCitation.cy.js @@ -89,4 +89,14 @@ describe('SciELO Translations Fields - Original document citation features', fun cy.waitJQuery(); cy.contains('h1', 'Submission complete'); }); + it('Original document citation is shown at workflow', function () { + cy.login('ckwantes', null, 'publicknowledge'); + cy.findSubmission('myQueue', submissionData.title); + + cy.get('#publication-button').click(); + cy.get('#translationData-button').click(); + + cy.contains('Original document citation'); + cy.get('input[name="originalDocumentCitation"]').should('have.value', submissionData.originalDoiCitation); + }); }); \ No newline at end of file From 8bc4cfa8490aef6fba58d3051ea18240eb25c0db Mon Sep 17 00:00:00 2001 From: Jhon Date: Mon, 2 Dec 2024 17:33:53 -0400 Subject: [PATCH 04/23] Refactors citation in integration test Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- cypress/tests/Test3_originalCitation.cy.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cypress/tests/Test3_originalCitation.cy.js b/cypress/tests/Test3_originalCitation.cy.js index f749be2..18b80ef 100644 --- a/cypress/tests/Test3_originalCitation.cy.js +++ b/cypress/tests/Test3_originalCitation.cy.js @@ -43,10 +43,10 @@ describe('SciELO Translations Fields - Original document citation features', fun abstract: 'Great guitar solos', keywords: ['guitar'], originalDoi: '10.1590/0037-8682-0167-2020', - originalDoiCitation: 'Croda, J., Oliveira, W. K. de ., Frutuoso, R. L. ., Mandetta, L. H. ., \ - Baia-da-Silva, D. C. ., Brito-Sousa, J. D. ., Monteiro, W. M. ., & Lacerda, M. V. G. . (2020). \ + originalDoiCitation: 'Croda, J., Oliveira, W. K. de, Frutuoso, R. L., Mandetta, L. H., \ + Baia-da-Silva, D. C., Brito-Sousa, J. D., Monteiro, W. M., & Lacerda, M. V. G. (2020). \ COVID-19 in Brazil: advantages of a socialized unified health system and preparation to contain cases. \ - In SciELO Preprints. https://doi.org/10.1590/0037-8682-0167-2020 (Original work published 2020)', + Revista Da Sociedade Brasileira de Medicina Tropical, 53. https://doi.org/10.1590/0037-8682-0167-2020', contributors: [ { 'given': 'Jimi', From 78d0814fcef786d0b6c80ef5fe2bb9e1920f72f4 Mon Sep 17 00:00:00 2001 From: Jhon Date: Mon, 2 Dec 2024 18:15:41 -0400 Subject: [PATCH 05/23] Creates unit test - Getting of DOI citation Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- .gitlab-ci.yml | 3 ++- tests/DoiClientTest.php | 43 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tests/DoiClientTest.php diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 439ee29..b24d4ad 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,4 +6,5 @@ include: ref: main file: - 'templates/groups/pkp_plugin.yml' - - 'templates/groups/ops/cypress_tests.yml' \ No newline at end of file + - 'templates/groups/ops/cypress_tests.yml' + - 'templates/groups/ops/unit_tests.yml' \ No newline at end of file diff --git a/tests/DoiClientTest.php b/tests/DoiClientTest.php new file mode 100644 index 0000000..192250a --- /dev/null +++ b/tests/DoiClientTest.php @@ -0,0 +1,43 @@ +mockGuzzleClient = $this->createMockGuzzleClient(); + $this->doiClient = new DoiClient($this->mockGuzzleClient); + } + + private function createMockGuzzleClient() + { + $mockResponse = new Response(200, [], $this->expectedDoiCitation); + $mockHandler = new MockHandler($mockResponse); + $guzzleClient = new Client(['handler' => $mockHandler]); + + return $guzzleClient; + } + + public function testGetDoiApaCitation() + { + $doiApaCitation = $this->doiClient->getApaCitation($this->originalDocumentDoi); + + $this->assertEquals($this->expectedDoiCitation, $doiApaCitation); + } +} From 1a975c902793a6432122aaa64afdd9958534d110 Mon Sep 17 00:00:00 2001 From: Jhon Date: Tue, 3 Dec 2024 14:29:19 -0400 Subject: [PATCH 06/23] Refactors integration test Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- cypress/tests/Test3_originalCitation.cy.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cypress/tests/Test3_originalCitation.cy.js b/cypress/tests/Test3_originalCitation.cy.js index 18b80ef..b2852a6 100644 --- a/cypress/tests/Test3_originalCitation.cy.js +++ b/cypress/tests/Test3_originalCitation.cy.js @@ -81,6 +81,7 @@ describe('SciELO Translations Fields - Original document citation features', fun cy.contains('The original document has a DOI'); cy.contains(submissionData.originalDoi); + cy.contains(submissionData.originalDoiCitation); cy.contains('button', 'Submit').click(); cy.get('.modal__panel:visible').within(() => { @@ -97,6 +98,6 @@ describe('SciELO Translations Fields - Original document citation features', fun cy.get('#translationData-button').click(); cy.contains('Original document citation'); - cy.get('input[name="originalDocumentCitation"]').should('have.value', submissionData.originalDoiCitation); + cy.contains(submissionData.originalDoiCitation); }); }); \ No newline at end of file From 73e76c1e942ca041f8997478f803ee0cbe49c2fc Mon Sep 17 00:00:00 2001 From: Jhon Date: Tue, 3 Dec 2024 15:25:53 -0400 Subject: [PATCH 07/23] Adds DOI client class Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- classes/clients/DoiClient.php | 43 +++++++++++++++++++++++++++++++++++ tests/DoiClientTest.php | 4 ++-- 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 classes/clients/DoiClient.php diff --git a/classes/clients/DoiClient.php b/classes/clients/DoiClient.php new file mode 100644 index 0000000..bcf263c --- /dev/null +++ b/classes/clients/DoiClient.php @@ -0,0 +1,43 @@ +guzzleClient = $guzzleClient; + } else { + $this->guzzleClient = Application::get()->getHttpClient(); + } + } + + public function getApaCitation(string $doi): ?string + { + $doiUrl = self::DOI_URL . $doi; + + try { + $response = $this->guzzleClient->request('GET', $doiUrl, [ + 'headers' => [ + 'Accept' => 'text/x-bibliography; style=apa' + ], + ]); + + return $response->getBody()->getContents(); + } catch (ClientException $e) { + $errorMsg = $e->getResponse()->getBody()->getContents(); + error_log("Error while getting DOI citation: $errorMsg"); + } + + return null; + } +} diff --git a/tests/DoiClientTest.php b/tests/DoiClientTest.php index 192250a..c2137da 100644 --- a/tests/DoiClientTest.php +++ b/tests/DoiClientTest.php @@ -7,7 +7,7 @@ use APP\submission\Submission; use APP\publication\Publication; use APP\facades\Repo; -use APP\plugins\reports\scieloTranslationsFields\classes\clients\DoiClient; +use APP\plugins\generic\scieloTranslationsFields\classes\clients\DoiClient; class DoiClientTest extends TestCase { @@ -28,7 +28,7 @@ public function setUp(): void private function createMockGuzzleClient() { $mockResponse = new Response(200, [], $this->expectedDoiCitation); - $mockHandler = new MockHandler($mockResponse); + $mockHandler = new MockHandler([$mockResponse]); $guzzleClient = new Client(['handler' => $mockHandler]); return $guzzleClient; From 3f1d5517cd2d53d0ea18928b51f9e4579e515b08 Mon Sep 17 00:00:00 2001 From: Jhon Date: Tue, 3 Dec 2024 16:56:17 -0400 Subject: [PATCH 08/23] Replaces publication handler by self handler Issue: documentacao-e-tarefas/scielo#721 Signed-off-by: Jhon --- ScieloTranslationsFieldsPlugin.php | 30 ++++++- .../TranslationsFieldsHandler.php | 80 +++++++++++++++++++ 2 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 api/v1/translationsFields/TranslationsFieldsHandler.php diff --git a/ScieloTranslationsFieldsPlugin.php b/ScieloTranslationsFieldsPlugin.php index 965b55d..f39718a 100644 --- a/ScieloTranslationsFieldsPlugin.php +++ b/ScieloTranslationsFieldsPlugin.php @@ -18,6 +18,7 @@ use PKP\plugins\GenericPlugin; use APP\core\Application; use APP\pages\submission\SubmissionHandler; +use APP\plugins\generic\scieloTranslationsFields\api\v1\translationsFields\TranslationsFieldsHandler; use APP\plugins\generic\scieloTranslationsFields\classes\components\forms\TranslationDataForm; class ScieloTranslationsFieldsPlugin extends GenericPlugin @@ -36,6 +37,7 @@ public function register($category, $path, $mainContextId = null) Hook::add('Template::Workflow', [$this, 'removeRelationsFromWorkflow']); Hook::add('TemplateManager::display', [$this, 'addResourcesToWorkflow']); Hook::add('Template::Workflow::Publication', [$this, 'addTranslationDataTabToWorkflow']); + Hook::add('Dispatcher::dispatch', [$this, 'setupTranslationsFieldsHandler']); Hook::add('Schema::get::publication', [$this, 'addOurFieldsToPublicationSchema']); } @@ -123,9 +125,9 @@ private function removeRelationsSection($stepSections) private function getTranslationDataForm($submission, $request) { $context = $request->getContext(); - $publication = $submission->getLatestPublication(); - $publicationEndpoint = 'submissions/' . $submission->getId() . '/publications/' . $publication->getId(); - $saveFormUrl = $request->getDispatcher()->url($request, Application::ROUTE_API, $context->getPath(), $publicationEndpoint); + $saveFormUrl = $request + ->getDispatcher() + ->url($request, Application::ROUTE_API, $context->getPath(), "translationsFields/saveTranslationFields", null, null, ['submissionId' => $submission->getId()]); return new TranslationDataForm($saveFormUrl, $submission); } @@ -236,6 +238,28 @@ public function addTranslationDataTabToWorkflow($hookName, $params) return Hook::CONTINUE; } + + public function setupTranslationsFieldsHandler($hookName, $params) + { + $request = $params[0]; + $router = $request->getRouter(); + + if (!($router instanceof \PKP\core\APIRouter)) { + return; + } + + if (str_contains($request->getRequestPath(), 'api/v1/translationsFields')) { + $handler = new TranslationsFieldsHandler(); + } + + if (!isset($handler)) { + return; + } + + $router->setHandler($handler); + $handler->getApp()->run(); + exit; + } } if (!PKP_STRICT_MODE) { diff --git a/api/v1/translationsFields/TranslationsFieldsHandler.php b/api/v1/translationsFields/TranslationsFieldsHandler.php new file mode 100644 index 0000000..4c2a05f --- /dev/null +++ b/api/v1/translationsFields/TranslationsFieldsHandler.php @@ -0,0 +1,80 @@ +_handlerPath = 'translationsFields'; + $roles = [Role::ROLE_ID_MANAGER, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_AUTHOR]; + $this->_endpoints = [ + 'PUT' => [ + [ + 'pattern' => $this->getEndpointPattern() . '/saveTranslationFields', + 'handler' => [$this, 'saveTranslationFields'], + 'roles' => $roles + ], + ], + ]; + parent::__construct(); + } + + public function authorize($request, &$args, $roleAssignments) + { + $rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES); + + foreach ($roleAssignments as $role => $operations) { + $rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations)); + } + $this->addPolicy($rolePolicy); + + return parent::authorize($request, $args, $roleAssignments); + } + + private function getSubmission($slimRequest) + { + $queryParams = $slimRequest->getQueryParams(); + $submissionId = (int) $queryParams['submissionId']; + + return Repo::submission()->get($submissionId); + } + + public function saveTranslationFields($slimRequest, $response, $args) + { + $requestParams = $slimRequest->getParsedBody(); + $submission = $this->getSubmission($slimRequest); + $publication = $submission->getCurrentPublication(); + + $originalDocumentHasDoi = $requestParams['originalDocumentHasDoi']; + $originalDocumentDoi = $requestParams['originalDocumentDoi']; + + Repo::publication()->edit($publication, [ + 'originalDocumentHasDoi' => $originalDocumentHasDoi, + 'originalDocumentDoi' => $originalDocumentDoi + ]); + + $submission = Repo::submission()->get($submission->getId()); + $publication = $submission->getCurrentPublication(); + + $contextId = $submission->getData('contextId'); + $userGroups = Repo::userGroup()->getCollector() + ->filterByContextIds([$contextId]) + ->getMany(); + + $genreDao = DAORegistry::getDAO('GenreDAO'); + $genres = $genreDao->getByContextId($contextId)->toArray(); + + return $response->withJson( + Repo::publication()->getSchemaMap($submission, $userGroups, $genres)->map($publication), + 200 + ); + } +} From 429c164996b11d454ced81971bba58c1f6453ecd Mon Sep 17 00:00:00 2001 From: Jhon Date: Tue, 3 Dec 2024 17:46:49 -0400 Subject: [PATCH 09/23] Adds original document citation on submission wizard Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- ScieloTranslationsFieldsPlugin.php | 5 +++++ .../TranslationsFieldsHandler.php | 9 ++++++++- locale/en/locale.po | 3 +++ locale/es/locale.po | 3 +++ locale/pt_BR/locale.po | 3 +++ templates/review/translationDataFields.tpl | 13 +++++++++++++ 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/ScieloTranslationsFieldsPlugin.php b/ScieloTranslationsFieldsPlugin.php index f39718a..20c2c8a 100644 --- a/ScieloTranslationsFieldsPlugin.php +++ b/ScieloTranslationsFieldsPlugin.php @@ -68,6 +68,11 @@ public function addOurFieldsToPublicationSchema($hookName, $params) 'apiSummary' => true, 'validation' => ['nullable'], ]; + $schema->properties->{'originalDocumentCitation'} = (object) [ + 'type' => 'string', + 'apiSummary' => true, + 'validation' => ['nullable'], + ]; return Hook::CONTINUE; } diff --git a/api/v1/translationsFields/TranslationsFieldsHandler.php b/api/v1/translationsFields/TranslationsFieldsHandler.php index 4c2a05f..b6f0b82 100644 --- a/api/v1/translationsFields/TranslationsFieldsHandler.php +++ b/api/v1/translationsFields/TranslationsFieldsHandler.php @@ -8,6 +8,7 @@ use PKP\security\authorization\RoleBasedHandlerOperationPolicy; use PKP\db\DAORegistry; use APP\facades\Repo; +use APP\plugins\generic\scieloTranslationsFields\classes\clients\DoiClient; class TranslationsFieldsHandler extends APIHandler { @@ -56,9 +57,15 @@ public function saveTranslationFields($slimRequest, $response, $args) $originalDocumentHasDoi = $requestParams['originalDocumentHasDoi']; $originalDocumentDoi = $requestParams['originalDocumentDoi']; + if ($originalDocumentDoi) { + $doiClient = new DoiClient(); + $originalDocumentCitation = $doiClient->getApaCitation($originalDocumentDoi); + } + Repo::publication()->edit($publication, [ 'originalDocumentHasDoi' => $originalDocumentHasDoi, - 'originalDocumentDoi' => $originalDocumentDoi + 'originalDocumentDoi' => $originalDocumentDoi, + 'originalDocumentCitation' => $originalDocumentCitation ]); $submission = Repo::submission()->get($submission->getId()); diff --git a/locale/en/locale.po b/locale/en/locale.po index 3c8c24a..69a8163 100644 --- a/locale/en/locale.po +++ b/locale/en/locale.po @@ -41,5 +41,8 @@ msgstr "DOI" msgid "plugins.generic.scieloTranslationsFields.originalDocumentDoi.description" msgstr "Please insert the DOI of the original document this submission is translating" +msgid "plugins.generic.scieloTranslationsFields.originalDocumentCitation" +msgstr "Original document citation" + msgid "plugins.generic.scieloTranslationsFields.error.originalDocumentHasDoi.required" msgstr "You must inform if the original document has a DOI" diff --git a/locale/es/locale.po b/locale/es/locale.po index f97729d..5e980c4 100644 --- a/locale/es/locale.po +++ b/locale/es/locale.po @@ -41,5 +41,8 @@ msgstr "DOI" msgid "plugins.generic.scieloTranslationsFields.originalDocumentDoi.description" msgstr "Por favor ingresse el DOI del documento original que este envío está traduciendo" +msgid "plugins.generic.scieloTranslationsFields.originalDocumentCitation" +msgstr "Cita del documento original" + msgid "plugins.generic.scieloTranslationsFields.error.originalDocumentHasDoi.required" msgstr "Debe informar si el documento original tiene DOI" diff --git a/locale/pt_BR/locale.po b/locale/pt_BR/locale.po index 5561dcd..6bc79be 100644 --- a/locale/pt_BR/locale.po +++ b/locale/pt_BR/locale.po @@ -41,5 +41,8 @@ msgstr "DOI" msgid "plugins.generic.scieloTranslationsFields.originalDocumentDoi.description" msgstr "Por favor, insira o DOI do documento original que esta submissão está traduzindo" +msgid "plugins.generic.scieloTranslationsFields.originalDocumentCitation" +msgstr "Citação do documento original" + msgid "plugins.generic.scieloTranslationsFields.error.originalDocumentHasDoi.required" msgstr "Você deve informar se o documento original possui um DOI" diff --git a/templates/review/translationDataFields.tpl b/templates/review/translationDataFields.tpl index 50e0a0a..59f92ec 100644 --- a/templates/review/translationDataFields.tpl +++ b/templates/review/translationDataFields.tpl @@ -44,5 +44,18 @@ +
+

+ {translate key="plugins.generic.scieloTranslationsFields.originalDocumentCitation"} +

+
+ +
+
\ No newline at end of file From c7498de17bc84f32e72c22e49cfe4bb2a6f1b96b Mon Sep 17 00:00:00 2001 From: Jhon Date: Tue, 3 Dec 2024 17:55:17 -0400 Subject: [PATCH 10/23] Refactors string in integration test Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- cypress/tests/Test3_originalCitation.cy.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cypress/tests/Test3_originalCitation.cy.js b/cypress/tests/Test3_originalCitation.cy.js index b2852a6..d7c9faa 100644 --- a/cypress/tests/Test3_originalCitation.cy.js +++ b/cypress/tests/Test3_originalCitation.cy.js @@ -43,10 +43,7 @@ describe('SciELO Translations Fields - Original document citation features', fun abstract: 'Great guitar solos', keywords: ['guitar'], originalDoi: '10.1590/0037-8682-0167-2020', - originalDoiCitation: 'Croda, J., Oliveira, W. K. de, Frutuoso, R. L., Mandetta, L. H., \ - Baia-da-Silva, D. C., Brito-Sousa, J. D., Monteiro, W. M., & Lacerda, M. V. G. (2020). \ - COVID-19 in Brazil: advantages of a socialized unified health system and preparation to contain cases. \ - Revista Da Sociedade Brasileira de Medicina Tropical, 53. https://doi.org/10.1590/0037-8682-0167-2020', + originalDoiCitationPart: 'COVID-19 in Brazil: advantages of a socialized unified health system and preparation to contain cases.', contributors: [ { 'given': 'Jimi', @@ -81,7 +78,7 @@ describe('SciELO Translations Fields - Original document citation features', fun cy.contains('The original document has a DOI'); cy.contains(submissionData.originalDoi); - cy.contains(submissionData.originalDoiCitation); + cy.contains(submissionData.originalDoiCitationPart); cy.contains('button', 'Submit').click(); cy.get('.modal__panel:visible').within(() => { @@ -98,6 +95,6 @@ describe('SciELO Translations Fields - Original document citation features', fun cy.get('#translationData-button').click(); cy.contains('Original document citation'); - cy.contains(submissionData.originalDoiCitation); + cy.contains(submissionData.originalDoiCitationPart); }); }); \ No newline at end of file From 91845f871ec45fe9af75df43218695a11198b29f Mon Sep 17 00:00:00 2001 From: Jhon Date: Wed, 4 Dec 2024 12:56:57 -0400 Subject: [PATCH 11/23] Shows original document citation on workflow Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- ScieloTranslationsFieldsPlugin.php | 8 ++++---- classes/components/forms/TranslationDataForm.php | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/ScieloTranslationsFieldsPlugin.php b/ScieloTranslationsFieldsPlugin.php index 20c2c8a..916cef2 100644 --- a/ScieloTranslationsFieldsPlugin.php +++ b/ScieloTranslationsFieldsPlugin.php @@ -127,19 +127,19 @@ private function removeRelationsSection($stepSections) return $editedSections; } - private function getTranslationDataForm($submission, $request) + private function getTranslationDataForm($submission, $request, $placedOn) { $context = $request->getContext(); $saveFormUrl = $request ->getDispatcher() ->url($request, Application::ROUTE_API, $context->getPath(), "translationsFields/saveTranslationFields", null, null, ['submissionId' => $submission->getId()]); - return new TranslationDataForm($saveFormUrl, $submission); + return new TranslationDataForm($saveFormUrl, $submission, $placedOn); } private function addTranslationDataSection($stepSections, $submission, $request) { - $translationDataForm = $this->getTranslationDataForm($submission, $request); + $translationDataForm = $this->getTranslationDataForm($submission, $request, 'submissionWizard'); $stepSections[] = [ 'id' => 'translationData', @@ -225,7 +225,7 @@ public function addResourcesToWorkflow($hookName, $params) return Hook::CONTINUE; } - $translationDataForm = $this->getTranslationDataForm($submission, $request); + $translationDataForm = $this->getTranslationDataForm($submission, $request, 'workflow'); $components = $templateMgr->getState('components'); $components[$translationDataForm->id] = $translationDataForm->getConfig(); diff --git a/classes/components/forms/TranslationDataForm.php b/classes/components/forms/TranslationDataForm.php index 69fe04e..0b83ac0 100644 --- a/classes/components/forms/TranslationDataForm.php +++ b/classes/components/forms/TranslationDataForm.php @@ -5,15 +5,17 @@ use PKP\components\forms\FormComponent; use PKP\components\forms\FieldOptions; use PKP\components\forms\FieldText; +use PKP\components\forms\FieldHTML; class TranslationDataForm extends FormComponent { public $id = 'translationData'; public $method = 'PUT'; - public function __construct($action, $submission) + public function __construct($action, $submission, $placedOn) { $publication = $submission->getCurrentPublication(); + $originalDocumentDoi = $publication->getData('originalDocumentDoi'); $this->action = $action; $this->addField(new FieldOptions('originalDocumentHasDoi', [ @@ -37,8 +39,17 @@ public function __construct($action, $submission) 'label' => __('plugins.generic.scieloTranslationsFields.originalDocumentDoi'), 'description' => __('plugins.generic.scieloTranslationsFields.originalDocumentDoi.description'), 'isMultilingual' => false, - 'value' => $publication->getData('originalDocumentDoi'), + 'value' => $originalDocumentDoi, 'showWhen' => ['originalDocumentHasDoi', 1] ])); + + if (!empty($originalDocumentDoi) && $placedOn = 'workflow') { + $originalDocumentCitation = $publication->getData('originalDocumentCitation'); + + $this->addField(new FieldHTML('originalDocumentDoi', [ + 'label' => __('plugins.generic.scieloTranslationsFields.originalDocumentCitation'), + 'description' => "

{$originalDocumentCitation}

", + ])); + } } } From a7e879631ca6c10f9c0567b5f113c96ae49402fd Mon Sep 17 00:00:00 2001 From: Jhon Date: Wed, 4 Dec 2024 14:40:50 -0400 Subject: [PATCH 12/23] Checks DOI input in integration test Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- cypress/tests/Test2_originalDoiField.cy.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cypress/tests/Test2_originalDoiField.cy.js b/cypress/tests/Test2_originalDoiField.cy.js index dca8936..1981aaa 100644 --- a/cypress/tests/Test2_originalDoiField.cy.js +++ b/cypress/tests/Test2_originalDoiField.cy.js @@ -90,6 +90,10 @@ describe('SciELO Translations Fields - Original DOI features', function () { cy.get('input[name="originalDocumentHasDoi"][value="1"]').check(); cy.contains('label', 'DOI'); cy.contains('Please insert the DOI of the original document this submission is translating'); + cy.get('input[name="originalDocumentDoi"]').type('Invalid DOI', {delay: 0}); + cy.contains('button', 'Continue').click(); + cy.contains('The DOI entered is invalid. Please include only the identifier (e.g. "10.1234/ExampleDOI")'); + cy.get('input[name="originalDocumentDoi"]').type(submissionData.originalDoi, {delay: 0}); Cypress._.times(4, () => { cy.contains('button', 'Continue').click(); From 5d66c6824d25dfd45f4d0db4f25d24114b0095bb Mon Sep 17 00:00:00 2001 From: Jhon Date: Wed, 4 Dec 2024 14:41:46 -0400 Subject: [PATCH 13/23] Fixes minor bug in form Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- classes/components/forms/TranslationDataForm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/components/forms/TranslationDataForm.php b/classes/components/forms/TranslationDataForm.php index 0b83ac0..50015b4 100644 --- a/classes/components/forms/TranslationDataForm.php +++ b/classes/components/forms/TranslationDataForm.php @@ -43,7 +43,7 @@ public function __construct($action, $submission, $placedOn) 'showWhen' => ['originalDocumentHasDoi', 1] ])); - if (!empty($originalDocumentDoi) && $placedOn = 'workflow') { + if (!empty($originalDocumentDoi) && $placedOn == 'workflow') { $originalDocumentCitation = $publication->getData('originalDocumentCitation'); $this->addField(new FieldHTML('originalDocumentDoi', [ From a84a88a518bbea03837413d6614bf21a5660791f Mon Sep 17 00:00:00 2001 From: Jhon Date: Wed, 4 Dec 2024 15:00:06 -0400 Subject: [PATCH 14/23] Adds DOI validator class Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- classes/DoiValidator.php | 11 +++++++++++ tests/DoiValidatorTest.php | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 classes/DoiValidator.php create mode 100644 tests/DoiValidatorTest.php diff --git a/classes/DoiValidator.php b/classes/DoiValidator.php new file mode 100644 index 0000000..77cb197 --- /dev/null +++ b/classes/DoiValidator.php @@ -0,0 +1,11 @@ +assertTrue($doiValidator->validate('10.1000/xyz123')); + $this->assertTrue($doiValidator->validate('10.1038/nphys1170')); + $this->assertTrue($doiValidator->validate('10.1109/5.771073')); + } + + public function testValidateInvalidDoi() + { + $doiValidator = new DoiValidator(); + + $this->assertFalse($doiValidator->validate('10.1234')); + $this->assertFalse($doiValidator->validate('10.1038/abc!123')); + $this->assertFalse($doiValidator->validate('10./1000/abcd')); + } +} From 5c12c7749fc6cb3bd26ad012ec488f3496c7cde1 Mon Sep 17 00:00:00 2001 From: Jhon Date: Wed, 4 Dec 2024 15:27:01 -0400 Subject: [PATCH 15/23] Checks for DOI validation in submission wizard Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- cypress/tests/Test2_originalDoiField.cy.js | 5 ++++- cypress/tests/Test3_originalCitation.cy.js | 13 +++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/cypress/tests/Test2_originalDoiField.cy.js b/cypress/tests/Test2_originalDoiField.cy.js index 1981aaa..a620e67 100644 --- a/cypress/tests/Test2_originalDoiField.cy.js +++ b/cypress/tests/Test2_originalDoiField.cy.js @@ -91,9 +91,12 @@ describe('SciELO Translations Fields - Original DOI features', function () { cy.contains('label', 'DOI'); cy.contains('Please insert the DOI of the original document this submission is translating'); cy.get('input[name="originalDocumentDoi"]').type('Invalid DOI', {delay: 0}); - cy.contains('button', 'Continue').click(); + Cypress._.times(4, () => { + cy.contains('button', 'Continue').click(); + }); cy.contains('The DOI entered is invalid. Please include only the identifier (e.g. "10.1234/ExampleDOI")'); + cy.contains('.pkpSteps__step__label', 'Details').click(); cy.get('input[name="originalDocumentDoi"]').type(submissionData.originalDoi, {delay: 0}); Cypress._.times(4, () => { cy.contains('button', 'Continue').click(); diff --git a/cypress/tests/Test3_originalCitation.cy.js b/cypress/tests/Test3_originalCitation.cy.js index d7c9faa..58b29e4 100644 --- a/cypress/tests/Test3_originalCitation.cy.js +++ b/cypress/tests/Test3_originalCitation.cy.js @@ -69,13 +69,22 @@ describe('SciELO Translations Fields - Original document citation features', fun beginSubmission(submissionData); cy.get('input[name="originalDocumentHasDoi"][value="1"]').check(); - cy.get('input[name="originalDocumentDoi"]').type(submissionData.originalDoi, {delay: 0}); + cy.get('input[name="originalDocumentDoi"]').type('Invalid DOI', {delay: 0}); detailsStep(submissionData); cy.addSubmissionGalleys(submissionData.files); cy.contains('button', 'Continue').click(); contributorsStep(submissionData); cy.contains('button', 'Continue').click(); - + + cy.contains('The DOI entered is invalid'); + cy.contains('h4', 'Original document citation').should('not.exist'); + + cy.contains('.pkpSteps__step__label', 'Details').click(); + cy.get('input[name="originalDocumentDoi"]').type(submissionData.originalDoi, {delay: 0}); + Cypress._.times(4, () => { + cy.contains('button', 'Continue').click(); + }); + cy.contains('The original document has a DOI'); cy.contains(submissionData.originalDoi); cy.contains(submissionData.originalDoiCitationPart); From 9778ed4a52d149d88a0148e8ecc7736610efd547 Mon Sep 17 00:00:00 2001 From: Jhon Date: Wed, 4 Dec 2024 15:51:40 -0400 Subject: [PATCH 16/23] Checks if DOI is valid in submission wizard Issue: documentacao-e-tarefas/scielo#724 Signed-off-by: Jhon --- ScieloTranslationsFieldsPlugin.php | 8 ++++++++ .../translationsFields/TranslationsFieldsHandler.php | 10 +++++++++- classes/DoiValidator.php | 2 +- locale/en/locale.po | 3 +++ locale/es/locale.po | 3 +++ locale/pt_BR/locale.po | 3 +++ templates/review/translationDataFields.tpl | 8 ++++++-- tests/DoiValidatorTest.php | 4 ++-- 8 files changed, 35 insertions(+), 6 deletions(-) diff --git a/ScieloTranslationsFieldsPlugin.php b/ScieloTranslationsFieldsPlugin.php index 916cef2..1a08ffa 100644 --- a/ScieloTranslationsFieldsPlugin.php +++ b/ScieloTranslationsFieldsPlugin.php @@ -20,6 +20,7 @@ use APP\pages\submission\SubmissionHandler; use APP\plugins\generic\scieloTranslationsFields\api\v1\translationsFields\TranslationsFieldsHandler; use APP\plugins\generic\scieloTranslationsFields\classes\components\forms\TranslationDataForm; +use APP\plugins\generic\scieloTranslationsFields\classes\DoiValidator; class ScieloTranslationsFieldsPlugin extends GenericPlugin { @@ -185,6 +186,13 @@ public function validateSubmissionFields($hookName, $params) $errors['originalDocumentHasDoi'] = [__('plugins.generic.scieloTranslationsFields.error.originalDocumentHasDoi.required')]; } + $doiValidator = new DoiValidator(); + $originalDocumentDoi = $publication->getData('originalDocumentDoi'); + + if (!$doiValidator->validate($originalDocumentDoi)) { + $errors['originalDocumentDoi'] = [__('plugins.generic.scieloTranslationsFields.originalDocumentDoi.invalidDoi')]; + } + return Hook::CONTINUE; } diff --git a/api/v1/translationsFields/TranslationsFieldsHandler.php b/api/v1/translationsFields/TranslationsFieldsHandler.php index b6f0b82..828d762 100644 --- a/api/v1/translationsFields/TranslationsFieldsHandler.php +++ b/api/v1/translationsFields/TranslationsFieldsHandler.php @@ -9,6 +9,7 @@ use PKP\db\DAORegistry; use APP\facades\Repo; use APP\plugins\generic\scieloTranslationsFields\classes\clients\DoiClient; +use APP\plugins\generic\scieloTranslationsFields\classes\DoiValidator; class TranslationsFieldsHandler extends APIHandler { @@ -48,6 +49,12 @@ private function getSubmission($slimRequest) return Repo::submission()->get($submissionId); } + private function validateOriginalDoi($originalDocumentDoi) + { + $doiValidator = new DoiValidator(); + return $doiValidator->validate($originalDocumentDoi); + } + public function saveTranslationFields($slimRequest, $response, $args) { $requestParams = $slimRequest->getParsedBody(); @@ -56,8 +63,9 @@ public function saveTranslationFields($slimRequest, $response, $args) $originalDocumentHasDoi = $requestParams['originalDocumentHasDoi']; $originalDocumentDoi = $requestParams['originalDocumentDoi']; + $originalDocumentCitation = null; - if ($originalDocumentDoi) { + if ($originalDocumentHasDoi && $this->validateOriginalDoi($originalDocumentDoi)) { $doiClient = new DoiClient(); $originalDocumentCitation = $doiClient->getApaCitation($originalDocumentDoi); } diff --git a/classes/DoiValidator.php b/classes/DoiValidator.php index 77cb197..d33a03c 100644 --- a/classes/DoiValidator.php +++ b/classes/DoiValidator.php @@ -6,6 +6,6 @@ class DoiValidator { public function validate(string $doi): bool { - return preg_match('/^10\.\d{4,9}\/[-._;()\/:A-Z0-9]+$/i', $doi); + return (preg_match('/^10\.\d{4,9}\/[-._;()\/:A-Z0-9]+$/i', $doi) === 1); } } diff --git a/locale/en/locale.po b/locale/en/locale.po index 69a8163..ea69d3b 100644 --- a/locale/en/locale.po +++ b/locale/en/locale.po @@ -41,6 +41,9 @@ msgstr "DOI" msgid "plugins.generic.scieloTranslationsFields.originalDocumentDoi.description" msgstr "Please insert the DOI of the original document this submission is translating" +msgid "plugins.generic.scieloTranslationsFields.originalDocumentDoi.invalidDoi" +msgstr "The DOI entered is invalid. Please include only the identifier (e.g. \"10.1234/ExampleDOI\")" + msgid "plugins.generic.scieloTranslationsFields.originalDocumentCitation" msgstr "Original document citation" diff --git a/locale/es/locale.po b/locale/es/locale.po index 5e980c4..248964c 100644 --- a/locale/es/locale.po +++ b/locale/es/locale.po @@ -41,6 +41,9 @@ msgstr "DOI" msgid "plugins.generic.scieloTranslationsFields.originalDocumentDoi.description" msgstr "Por favor ingresse el DOI del documento original que este envío está traduciendo" +msgid "plugins.generic.scieloTranslationsFields.originalDocumentDoi.invalidDoi" +msgstr "El DOI introducido no es válido. Por favor, introduzca sólo el identificador (ex.: \"10.1234/ExemploDOI\")" + msgid "plugins.generic.scieloTranslationsFields.originalDocumentCitation" msgstr "Cita del documento original" diff --git a/locale/pt_BR/locale.po b/locale/pt_BR/locale.po index 6bc79be..5771ff9 100644 --- a/locale/pt_BR/locale.po +++ b/locale/pt_BR/locale.po @@ -41,6 +41,9 @@ msgstr "DOI" msgid "plugins.generic.scieloTranslationsFields.originalDocumentDoi.description" msgstr "Por favor, insira o DOI do documento original que esta submissão está traduzindo" +msgid "plugins.generic.scieloTranslationsFields.originalDocumentDoi.invalidDoi" +msgstr "O DOI inserido é inválido. Por favor, insira apenas o identificador (ex.: \"10.1234/ExemploDOI\")" + msgid "plugins.generic.scieloTranslationsFields.originalDocumentCitation" msgstr "Citação do documento original" diff --git a/templates/review/translationDataFields.tpl b/templates/review/translationDataFields.tpl index 59f92ec..2d09349 100644 --- a/templates/review/translationDataFields.tpl +++ b/templates/review/translationDataFields.tpl @@ -39,13 +39,17 @@ {translate key="plugins.generic.scieloTranslationsFields.originalDocumentDoi"}
-