Skip to content

Commit

Permalink
Fixed issue #18832: Participants can't re-enter a submitted survey if…
Browse files Browse the repository at this point in the history
… setting is using "inherit" at participant settings (#3312)

Co-authored-by: lapiudevgit <devgit@lapiu.biz>
Co-authored-by: tiborpacalat <129872163+tiborpacalat@users.noreply.github.com>
  • Loading branch information
3 people committed Aug 9, 2023
1 parent e0c71c2 commit 9275126
Show file tree
Hide file tree
Showing 4 changed files with 265 additions and 27 deletions.
4 changes: 2 additions & 2 deletions application/helpers/expressions/em_manager_helper.php
Expand Up @@ -5151,7 +5151,7 @@ private function _UpdateValuesInDatabase($finished = false)
LimeExpressionManager::addFrontendFlashMessage('error', $message, $this->sid);
return;
}
if ($oResponse->submitdate == null || Survey::model()->findByPk($this->sid)->alloweditaftercompletion == 'Y') {
if ($oResponse->submitdate == null || Survey::model()->findByPk($this->sid)->isAllowEditAfterCompletion) {
try {
$oResponse->setAllAttributes($aResponseAttributes, false);
} catch (Exception $ex) {
Expand Down Expand Up @@ -5200,7 +5200,7 @@ private function _UpdateValuesInDatabase($finished = false)
if ($aQuotas && !empty($aQuotas)) {
checkCompletedQuota($this->sid); // will create a page and quit: why not use it directly ?
} else {
if ($finished && ($oResponse->submitdate == null || Survey::model()->findByPk($this->sid)->alloweditaftercompletion == 'Y')) {
if ($finished && ($oResponse->submitdate == null || Survey::model()->findByPk($this->sid)->isAllowEditAfterCompletion)) {
/* Less update : just do what you need to to */
if ($this->surveyOptions['datestamp']) {
$submitdate = dateShift(date("Y-m-d H:i:s"), "Y-m-d H:i:s", $this->surveyOptions['timeadjust']);
Expand Down
55 changes: 30 additions & 25 deletions application/models/TokenDynamic.php
Expand Up @@ -810,11 +810,7 @@ public function getActions()
'iconClass' => 'ri-eye-fill',
'enabledCondition' => $permission_reponses_create
&& !$this->survey->isActive
&& !empty($this->token)
&& ($this->completed == "N"
|| empty($this->completed)
|| $this->survey->alloweditaftercompletion == "Y"
)
&& $this->canBeUsed()
];
$dropdownItems[] = [
'title' => gT('Launch the survey with this participant'),
Expand All @@ -827,10 +823,7 @@ public function getActions()
'iconClass' => 'ri-play-fill',
'enabledCondition' => $permission_reponses_create
&& $this->survey->isActive
&& !empty($this->token)
&& ($this->completed === "N"
|| empty($this->completed)
|| $this->survey->alloweditaftercompletion === "Y")
&& $this->canBeUsed()
];
$dropdownItems[] = [
'title' => gT('Send email invitation'),
Expand All @@ -840,18 +833,8 @@ public function getActions()
]),
'iconClass' => 'ri-mail-send-fill',
'enabledCondition' => $permission_tokens_update
&& !empty($this->token)
&& ($this->sent === "N" || empty($this->sent))
&& $this->emailstatus === "OK"
&& $this->email
&& $this->completed === "N"
&& ($this->usesleft > 0 || $this->survey->alloweditaftercompletion === "Y")
&& $this->survey->isActive
&& !empty($this->token)
&& ($this->completed === "N"
|| empty($this->completed)
|| $this->survey->alloweditaftercompletion === "Y"
)
&& $this->canBeEmailed()
];
$dropdownItems[] = [
'title' => gT('Send email reminder'),
Expand All @@ -861,12 +844,8 @@ public function getActions()
]),
'iconClass' => 'ri-mail-send-fill',
'enabledCondition' => $permission_tokens_update
&& !empty($this->token)
&& !($this->sent === "N" || empty($this->sent))
&& $this->emailstatus === "OK"
&& $this->email
&& $this->completed === "N"
&& ($this->usesleft > 0 || $this->survey->alloweditaftercompletion === "Y")
&& $this->canBeEmailed()
];
$dropdownItems[] = [
'title' => gT('Edit this survey participant'),
Expand Down Expand Up @@ -1079,4 +1058,30 @@ public function getSurveyId()
{
return self::$sid;
}

/**
* Returns true if the token can be used
* @return bool
*/
public function canBeUsed()
{
return !empty($this->token)
&& (
$this->completed == "N"
|| empty($this->completed)
|| $this->survey->isAllowEditAfterCompletion
);
}

public function canBeEmailed()
{
return !empty($this->token)
&& $this->emailstatus == "OK"
&& $this->email
&& $this->completed == "N"
&& (
$this->usesleft > 0
|| $this->survey->isAllowEditAfterCompletion
);
}
}
1 change: 1 addition & 0 deletions tests/functional/backend/NoGreenBarTest.php
Expand Up @@ -69,6 +69,7 @@ public function testNoGreenBar()
$web->findById('breadcrumb-container');
$this->assertTrue(true, 'Found green bar');
} catch (NoSuchElementException $ex) {
self::$testHelper->takeScreenshot(self::$webDriver, __CLASS__ . '_' . __FUNCTION__);
$this->assertTrue(false, 'Found no green bar, NoSuchElementException');
}
}
Expand Down
232 changes: 232 additions & 0 deletions tests/unit/models/TokenDynamicTest.php
@@ -0,0 +1,232 @@
<?php

namespace ls\tests;

use TokenDynamic;
use PHPUnit\Framework\TestCase;

class TokenDynamicTest extends TestBaseClass
{
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();

// Import survey.
$surveyFile = self::$surveysFolder . '/survey_archive_265831.lsa';
self::importSurvey($surveyFile);

TokenDynamic::model(self::$surveyId);
}

public function testTokenCanBeUsedWithoutTokenAttribute()
{
$token = new TokenDynamic(self::$surveyId);
$this->assertFalse($token->canBeUsed(), 'There is no token attribute, the token should not be able to be used.');
}

public function testTokenCanBeUsedWithCompletedAttributeUnset()
{
$tokenData = array(
'token' => 'a-token-string',
'completed' => '',
);

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);

$this->assertTrue($token->canBeUsed(), 'The completed attribute was not set, the token should be able to be used.');
}

public function testTokenCanBeUsedWithCompletedAttributeSetToNo()
{
$tokenData = array(
'token' => 'a-token-string',
'completed' => 'N',
);

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);

$this->assertTrue($token->canBeUsed(), 'The completed attribute was set to N, the token should be able to be used.');
}

public function testTokenCanBeUsedWithAllowEditAfterCompletionSetToNo()
{
$tokenData = array(
'token' => 'a-token-string',
'completed' => 'N',
);

self::$testSurvey->oOptions->alloweditaftercompletion = 'N';

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);

$this->assertTrue($token->canBeUsed(), 'The survey allow edit after completion attribute was set to N, the token should be able to be used.');
}

public function testTokenCanBeUsedWithAllowEditAfterCompletionSetToYes()
{
$tokenData = array(
'token' => 'a-token-string',
'completed' => 'N',
);

self::$testSurvey->oOptions->alloweditaftercompletion = 'Y';

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);

$this->assertTrue($token->canBeUsed(), 'The survey allow edit after completion attribute was set to Y, the token should be able to be used.');
}

public function testTokenCanBeUsedWithCompletedAttributeSetToYes()
{
$tokenData = array(
'token' => 'a-token-string',
'completed' => 'Y',
);

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);

$this->assertFalse($token->canBeUsed(), 'The completed attribute was set to Y, the token should not be able to be used.');
}

public function testCompletedTokenCanBeUsedWithAllowEditAfterCompletionSetToNo()
{
$tokenData = array(
'token' => 'a-token-string',
'completed' => 'Y',
);

self::$testSurvey->oOptions->alloweditaftercompletion = 'N';

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);

$this->assertFalse($token->canBeUsed(), 'The survey allow edit after completion attribute was set to N, the token should not be able to be used.');
}

public function testCompletedTokenCanBeUsedWithAllowEditAfterCompletionSetToYes()
{
$tokenData = array(
'token' => 'a-token-string',
'completed' => 'Y',
);

self::$testSurvey->oOptions->alloweditaftercompletion = 'Y';

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);

$this->assertFalse($token->canBeUsed(), 'The survey allow edit after completion attribute was set to Y, the token should be able be used.');
}

public function testTokenCanBeEmailedWithoutTokenAttribute()
{
$token = new TokenDynamic(self::$surveyId);
$this->assertFalse($token->canBeEmailed(), 'There is no token attribute, the token should not be able to be emailed.');
}

public function testTokenCanBeEmailedWithEmailStatusOk()
{
$tokenData = array(
'token' => 'a-token-string',
'emailstatus' => 'OK',
'email' => 'user@example.com',
'completed' => 'N',
'usesleft' => 1,
);

self::$testSurvey->oOptions->alloweditaftercompletion = 'N';

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);
$this->assertTrue($token->canBeEmailed(), 'Email status is ok, the token should be able to be emailed.');
}

public function testTokenCanBeEmailedWithEmailStatusNotOk()
{
$tokenData = array(
'token' => 'a-token-string',
'emailstatus' => '',
'email' => 'user@example.com',
'completed' => 'N',
'usesleft' => 1,
);

self::$testSurvey->oOptions->alloweditaftercompletion = 'N';

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);
$this->assertFalse($token->canBeEmailed(), 'Email status is empty, the token should not be able to be emailed.');
}

public function testTokenCanBeEmailedNoEmailSet()
{
$tokenData = array(
'token' => 'a-token-string',
'emailstatus' => 'OK',
'completed' => 'N',
'usesleft' => 1,
);

self::$testSurvey->oOptions->alloweditaftercompletion = 'N';

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);
$this->assertFalse($token->canBeEmailed(), 'Email was not set, the token should not be able to be emailed.');
}

public function testTokenCanBeEmailedWithCompletedAttributeSetToYes()
{
$tokenData = array(
'token' => 'a-token-string',
'emailstatus' => 'OK',
'email' => 'user@example.com',
'completed' => 'Y',
'usesleft' => 1,
);

self::$testSurvey->oOptions->alloweditaftercompletion = 'N';

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);
$this->assertFalse($token->canBeEmailed(), 'Completes was set to Y, the token should not be able to be emailed.');
}

public function testTokenCanBeEmailedWithNoUsesLeft()
{
$tokenData = array(
'token' => 'a-token-string',
'emailstatus' => 'OK',
'email' => 'user@example.com',
'completed' => 'N',
'usesleft' => 0,
);

self::$testSurvey->oOptions->alloweditaftercompletion = 'N';

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);
$this->assertFalse($token->canBeEmailed(), 'No uses left, the token should not be able to be emailed.');
}

public function testTokenCanBeEmailedWithSurveyAllowAfterCompletionSetToYes()
{
$tokenData = array(
'token' => 'a-token-string',
'emailstatus' => 'OK',
'email' => 'user@example.com',
'completed' => 'N',
'usesleft' => 0,
);

self::$testSurvey->oOptions->alloweditaftercompletion = 'Y';

$token = new TokenDynamic(self::$surveyId);
$token->setAttributes($tokenData, false);
$this->assertFalse($token->canBeEmailed(), 'Survey can be edited after completion, the token should not be able to be emailed.');
}
}

0 comments on commit 9275126

Please sign in to comment.