Skip to content

Commit

Permalink
Merge branch 'dataConsentChanges-690' into 'main'
Browse files Browse the repository at this point in the history
Mudanças em relação ao consentimento de dados

See merge request softwares-pkp/plugins_ojs/demographicData!10
  • Loading branch information
JhonathanLepidus committed Aug 13, 2024
2 parents 248acc7 + 6634658 commit 34a3c07
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 11 deletions.
12 changes: 12 additions & 0 deletions classes/DemographicDataService.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@ public function registerExternalAuthorResponses(string $externalId, string $exte
}
}

public function deleteUserResponses(int $userId, int $contextId)
{
$userResponses = Repo::demographicResponse()->getCollector()
->filterByContextIds([$contextId])
->filterByUserIds([$userId])
->getMany();

foreach ($userResponses as $response) {
Repo::demographicResponse()->delete($response);
}
}

public function authorAlreadyAnsweredQuestionnaire($author, $authorOrcid = null): bool
{
$externalId = $author->getData('email');
Expand Down
15 changes: 15 additions & 0 deletions classes/demographicResponse/Collector.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class Collector implements CollectorInterface
public DAO $dao;
public ?array $questionIds = null;
public ?array $userIds = null;
public ?array $contextIds = null;
public ?array $externalIds = null;
public ?array $externalTypes = null;

Expand All @@ -32,6 +33,12 @@ public function filterByUserIds(?array $userIds): Collector
return $this;
}

public function filterByContextIds(?array $contextIds): Collector
{
$this->contextIds = $contextIds;
return $this;
}

public function filterByExternalIds(?array $externalIds): Collector
{
$this->externalIds = $externalIds;
Expand All @@ -57,6 +64,14 @@ public function getQueryBuilder(): Builder
$queryBuilder->whereIn('demographic_responses.user_id', $this->userIds);
}

if (isset($this->contextIds)) {
$queryBuilder->whereIn('demographic_responses.demographic_question_id', function ($q) {
$q->select('dq.demographic_question_id')
->from('demographic_questions', 'dq')
->whereIn('dq.context_id', $this->contextIds);
});
}

if (isset($this->externalIds)) {
$queryBuilder->whereIn('demographic_responses.external_id', $this->externalIds);
}
Expand Down
13 changes: 8 additions & 5 deletions classes/form/QuestionsForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,19 @@ public function validate($callHooks = true)

public function execute(...$functionArgs)
{
$demographicDataDao = new DemographicDataDAO();
$demographicDataService = new DemographicDataService();
$context = $this->request->getContext();
$user = $this->request->getUser();
$consent = $this->getData('demographicDataConsent');
$previousConsent = $demographicDataDao->getDemographicConsent($context->getId(), $user->getId());
$newConsent = $this->getData('demographicDataConsent');

$demographicDataDao = new DemographicDataDAO();
$demographicDataDao->updateDemographicConsent($context->getId(), $user->getId(), $consent);
$demographicDataDao->updateDemographicConsent($context->getId(), $user->getId(), $newConsent);

if ($consent) {
$demographicDataService = new DemographicDataService();
if ($newConsent == '1') {
$demographicDataService->registerUserResponses($user->getId(), $this->getData('responses'));
} elseif ($newConsent == '0' and $previousConsent) {
$demographicDataService->deleteUserResponses($user->getId(), $context->getId());
}

parent::execute(...$functionArgs);
Expand Down
34 changes: 33 additions & 1 deletion cypress/tests/Test1_questionsDisplaying.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,19 @@ function assertResponsesToQuestionsInFrench() {
cy.get('select[id^="demographicResponses"] option:selected').should('have.text', 'Trois à cinq salaires minimums');
}

function assertDisabledFields() {
cy.get('input[id^="demographicResponses-en"]').eq(0).should('be.disabled');
cy.get('input[id^="demographicResponses-en"]').eq(1).should('be.disabled');
cy.get('textarea[id^="demographicResponses-en"]').should('be.disabled');
cy.contains('label', 'English').within(() => {
cy.get('input').should('be.disabled');
});
cy.contains('label', 'America').within(() => {
cy.get('input').should('be.disabled');
});
cy.get('select[id^="demographicResponses"]').should('be.disabled');
}

describe('Demographic Data - Questions displaying', function () {
it('Display of questions and request message at users profile page', function () {
cy.login('dbarnes', null, 'publicknowledge');
Expand All @@ -112,8 +125,10 @@ describe('Demographic Data - Questions displaying', function () {

cy.contains('I consent to the processing of my Demographic Data');
cy.contains('I do not consent to the processing of my Demographic Data');
cy.contains('You can change your consent option at any time.');
cy.contains('If you withdraw a previously given consent, your demographic data will be deleted');

cy.get('input[name="demographicDataConsent"][value=0]').should('be.checked');
cy.get('input[name="demographicDataConsent"][value=0]').should('not.be.checked');
cy.get('input[name="demographicDataConsent"][value=1]').should('not.be.checked');

cy.get('input[name="demographicDataConsent"][value=0]').click();
Expand All @@ -123,6 +138,7 @@ describe('Demographic Data - Questions displaying', function () {

cy.contains('a', 'Demographic Data').click();
cy.get('input[name="demographicDataConsent"][value=0]').should('be.checked');
assertDisabledFields();
});
it('Request message is not shown anymore', function () {
cy.login('dsokoloff', null, 'publicknowledge');
Expand All @@ -147,4 +163,20 @@ describe('Demographic Data - Questions displaying', function () {
cy.get('a[name="demographicData"]').click();
assertResponsesToQuestionsInFrench();
});
it('User removes consent, leading to data deletion', function () {
cy.login('dsokoloff', null, 'publicknowledge');
cy.get('.app__headerActions button').eq(1).click();
cy.contains('a', 'Edit Profile').click();
cy.contains('a', 'Demographic Data').click();

cy.get('input[name="demographicDataConsent"][value=0]').click();
cy.get('#demographicDataForm .submitFormButton').click();
cy.wait(1000);
cy.reload();

cy.contains('a', 'Demographic Data').click();
cy.get('input[id^="demographicResponses-en"]').eq(0).should('have.value', '');
cy.get('input[id^="demographicResponses-en"]').eq(1).should('have.value', '');
cy.get('textarea[id^="demographicResponses-en"]').should('have.value', '');
});
});
3 changes: 3 additions & 0 deletions locale/en/locale.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ msgstr "Adds custom questions for Demographic Data."
msgid "plugins.generic.demographicData.consent"
msgstr "Consent"

msgid "plugins.generic.demographicData.consent.description"
msgstr "You can change your consent option at any time. If you withdraw a previously given consent, your demographic data will be deleted."

msgid "plugins.generic.demographicData.consent.yes"
msgstr "I consent to the processing of my Demographic Data"

Expand Down
3 changes: 3 additions & 0 deletions locale/es/locale.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ msgstr "Agrega preguntas personalizadas para Datos Demográficos."
msgid "plugins.generic.demographicData.consent"
msgstr "Autorización"

msgid "plugins.generic.demographicData.consent.description"
msgstr "Puede cambiar su elección de consentimiento en cualquier momento. Si retira un consentimiento dado anteriormente, se eliminarán sus datos demográficos."

msgid "plugins.generic.demographicData.consent.yes"
msgstr "Autorizo el tratamiento de mis Datos Demográficos"

Expand Down
3 changes: 3 additions & 0 deletions locale/pt_BR/locale.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ msgstr "Adiciona perguntas personalizadas para Dados Demográficos."
msgid "plugins.generic.demographicData.consent"
msgstr "Consentimento"

msgid "plugins.generic.demographicData.consent.description"
msgstr "Você pode alterar sua opção de consentimento a qualquer momento. Se você remover um consentimento previamente dado, seus dados demográficos serão excluídos."

msgid "plugins.generic.demographicData.consent.yes"
msgstr "Eu concordo com o processamento dos meus Dados Demográficos"

Expand Down
30 changes: 26 additions & 4 deletions templates/questionsInProfile.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,16 @@
<form class="pkp_form" id="demographicDataForm" method="post" action="{url op="saveDemographicData"}" enctype="multipart/form-data">
{csrf}

{fbvFormSection list="false" label='plugins.generic.demographicData.consent'}
{fbvElement type="radio" id="demographicDataConsentYes" name="demographicDataConsent" value=1 checked=$demographicDataConsent required=true label="plugins.generic.demographicData.consent.yes"}
{fbvElement type="radio" id="demographicDataConsentNo" name="demographicDataConsent" value=0 checked=!$demographicDataConsent required=true label="plugins.generic.demographicData.consent.no"}
{fbvFormSection list="false" label='plugins.generic.demographicData.consent' description='plugins.generic.demographicData.consent.description' required=true}
{if is_null($demographicDataConsent)}
{assign var=checkedConsentYes value=false}
{assign var=checkedConsentNo value=false}
{else}
{assign var=checkedConsentYes value=$demographicDataConsent}
{assign var=checkedConsentNo value=!$demographicDataConsent}
{/if}
{fbvElement type="radio" id="demographicDataConsentYes" name="demographicDataConsent" value=1 checked=$checkedConsentYes required=true label="plugins.generic.demographicData.consent.yes"}
{fbvElement type="radio" id="demographicDataConsentNo" name="demographicDataConsent" value=0 checked=$checkedConsentNo required=true label="plugins.generic.demographicData.consent.no"}
{/fbvFormSection}

{fbvFormArea id="demographicQuestion"}
Expand All @@ -28,9 +35,24 @@
<script>
function setRequirementOnQuestions(required){ldelim}
let questions = document.querySelectorAll('[id^="demographicResponses"]');
let reqSymbols = document.querySelectorAll('span.req');
let reqErrorMessages = document.querySelectorAll('label.error');
for(let question of questions) {ldelim}
for (let question of questions) {ldelim}
question.required = required;
question.disabled = !required;
{rdelim}
for (let reqSymbol of reqSymbols) {ldelim}
let reqSymbolParent = reqSymbol.parentNode;
if (!reqSymbolParent.textContent.includes('{translate key="plugins.generic.demographicData.consent"}')) {ldelim}
reqSymbol.style.display = (required ? 'inline' : 'none');
{rdelim}
{rdelim}
for (let reqErrorMessage of reqErrorMessages) {ldelim}
reqErrorMessage.style.display = 'none';
{rdelim}
{rdelim}
Expand Down
32 changes: 31 additions & 1 deletion tests/demographicResponse/RepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,37 @@ public function testCollectorFilterByQuestionAndUser(): void
self::assertTrue(in_array($demographicResponse, $demographicResponses->all()));
}

public function testCollectorFilterByExternalId(): void
public function testCollectorFilterByContext(): void
{
$contextId = 1;
$repository = app(Repository::class);
$newParams = [
'demographicQuestionId' => $this->demographicQuestionId,
'userId' => null,
'responseValue' => [
self::DEFAULT_LOCALE => 'Test text 2'
],
'externalId' => null,
'externalType' => null
];

$firstDemographicResponse = $repository->newDataObject($this->params);
$secondDemographicResponse = $repository->newDataObject($newParams);

$repository->add($firstDemographicResponse);
$repository->add($secondDemographicResponse);

$demographicResponses = $repository->getCollector()
->filterByContextIds([$contextId])
->getMany()
->toArray();

self::assertEquals(2, count($demographicResponses));
self::assertTrue(in_array($firstDemographicResponse, $demographicResponses));
self::assertTrue(in_array($secondDemographicResponse, $demographicResponses));
}

public function testCollectorFilterByExternalIdAndType(): void
{
$newParams = [
'demographicQuestionId' => $this->demographicQuestionId,
Expand Down

0 comments on commit 34a3c07

Please sign in to comment.