Skip to content

Commit df155fa

Browse files
Merge pull request #47933 from nextcloud/bugfix/noid/throw-precondition-failure-when-not-matching
fix(config): Throw PreconditionException always when it didn't match
2 parents 6aa387e + dcd97e1 commit df155fa

2 files changed

Lines changed: 39 additions & 3 deletions

File tree

lib/private/AllConfig.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,10 @@ public function setUserValue($userId, $appName, $key, $value, $preCondition = nu
242242
$prevValue = $this->getUserValue($userId, $appName, $key, null);
243243

244244
if ($prevValue !== null) {
245-
if ($prevValue === (string)$value) {
246-
return;
247-
} elseif ($preCondition !== null && $prevValue !== (string)$preCondition) {
245+
if ($preCondition !== null && $prevValue !== (string)$preCondition) {
248246
throw new PreConditionNotMetException();
247+
} elseif ($prevValue === (string)$value) {
248+
return;
249249
} else {
250250
$qb = $this->connection->getQueryBuilder();
251251
$qb->update('preferences')

tests/lib/AllConfigTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,42 @@ public function testSetUserValueWithPreConditionFailure() {
182182
$config->deleteUserValue('userPreCond1', 'appPreCond', 'keyPreCond');
183183
}
184184

185+
public function testSetUserValueWithPreConditionFailureWhenResultStillMatches(): void {
186+
$this->expectException(\OCP\PreConditionNotMetException::class);
187+
188+
$config = $this->getConfig();
189+
190+
$selectAllSQL = 'SELECT `userid`, `appid`, `configkey`, `configvalue` FROM `*PREFIX*preferences` WHERE `userid` = ?';
191+
192+
$config->setUserValue('userPreCond1', 'appPreCond', 'keyPreCond', 'valuePreCond');
193+
194+
$result = $this->connection->executeQuery($selectAllSQL, ['userPreCond1'])->fetchAll();
195+
196+
$this->assertCount(1, $result);
197+
$this->assertEquals([
198+
'userid' => 'userPreCond1',
199+
'appid' => 'appPreCond',
200+
'configkey' => 'keyPreCond',
201+
'configvalue' => 'valuePreCond'
202+
], $result[0]);
203+
204+
// test if the method throws with invalid precondition when the value is the same
205+
$config->setUserValue('userPreCond1', 'appPreCond', 'keyPreCond', 'valuePreCond', 'valuePreCond3');
206+
207+
$result = $this->connection->executeQuery($selectAllSQL, ['userPreCond1'])->fetchAll();
208+
209+
$this->assertCount(1, $result);
210+
$this->assertEquals([
211+
'userid' => 'userPreCond1',
212+
'appid' => 'appPreCond',
213+
'configkey' => 'keyPreCond',
214+
'configvalue' => 'valuePreCond'
215+
], $result[0]);
216+
217+
// cleanup
218+
$config->deleteUserValue('userPreCond1', 'appPreCond', 'keyPreCond');
219+
}
220+
185221
public function testSetUserValueUnchanged() {
186222
// TODO - FIXME until the dependency injection is handled properly (in AllConfig)
187223
$this->markTestSkipped('Skipped because this is just testable if database connection can be injected');

0 commit comments

Comments
 (0)