Skip to content

Commit

Permalink
Merge pull request #779 from nextcloud/fix/777
Browse files Browse the repository at this point in the history
Avoid failures with link column database values from previous versions
  • Loading branch information
juliusknorr authored Jan 18, 2024
2 parents c85456a + 612c437 commit 36ae10d
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 8 deletions.
39 changes: 33 additions & 6 deletions lib/Service/ColumnTypes/TextLinkBusiness.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,30 @@ class TextLinkBusiness extends SuperBusiness implements IColumnTypeBusiness {
* @return string
*/
public function parseValue($value, ?Column $column = null): string {
if ($value === null) {
return '';
}

// if is import from export in format "[description] ([link])"
preg_match('/(.*) \((http.*)\)/', $value, $matches);
if (!empty($matches) && $matches[0] && $matches[1]) {
return json_encode(json_encode([
'title' => $matches[1],
'resourceUrl' => $matches[2]
'value' => $matches[2],
'providerId' => 'url',
]));
}

// if is json
// if is json (this is the default case, other formats are backward compatibility
$data = json_decode($value, true);
if($data !== null) {
if (isset($data['resourceUrl'])) {
return json_encode(json_encode([
'title' => $data['title'] ?? $data['resourceUrl'],
'value' => $data['resourceUrl'],
'providerId' => 'url',
]));
}
// at least title and resUrl have to be set
if(isset($data['title']) && isset($data['value'])) {
return json_encode($value);
Expand All @@ -40,7 +52,8 @@ public function parseValue($value, ?Column $column = null): string {
}
return json_encode(json_encode([
'title' => $matches[0],
'resourceUrl' => $matches[0]
'value' => $matches[0],
'providerId' => 'url',
]));
}

Expand All @@ -50,14 +63,28 @@ public function parseValue($value, ?Column $column = null): string {
* @return bool
*/
public function canBeParsed($value, ?Column $column = null): bool {
if (!$value) {
return true;
}
preg_match('/(.*) \((http.*)\)/', $value, $matches);
if (!empty($matches) && $matches[0] && $matches[1]) {
return true;
}

// if is json
$data = json_decode($value);
if($data != null) {
$data = json_decode($value, true);
if($data !== null) {
if (!isset($data['resourceUrl']) && !isset($data['value'])) {
$this->logger->error('Value ' . $value . ' cannot be parsed as the column ' . $column->getId(). ' as it contains incomplete data');
return false;
}

// Validate url providers
$allowedProviders = explode(',', $column->getTextAllowedPattern() ?? '') ?: [];
if (isset($data['providerId']) && !in_array($data['providerId'], $allowedProviders)) {
$this->logger->error('Value ' . $value . ' cannot be parsed as the column ' . $column->getId(). ' does not allow the provider: ' . $data['providerId']);
return false;
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default {
localValue: {
get() {
// if we got an old value (string not object as json)
if (!this.hasJsonStructure(this.value) && this.value !== '' && this.value !== null && this.value !== '""') {
if (this.value && !this.hasJsonStructure(this.value)) {
return {
title: this.value,
subline: t('tables', 'URL'),
Expand All @@ -80,7 +80,7 @@ export default {
}
}
return JSON.parse(this.value)
return this.value ? JSON.parse(this.value) : null
},
set(v) {
let value = null
Expand Down
105 changes: 105 additions & 0 deletions tests/unit/Service/ColumnTypes/TextLinkBusinessTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php
/**
* @copyright Copyright (c) 2024 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @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 <http://www.gnu.org/licenses/>.
*/

namespace OCA\Tables\Service\ColumnTypes;

use OCA\Tables\Db\Column;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;

class TextLinkBusinessTest extends TestCase {

private TextLinkBusiness $textLink;

public function setUp(): void {
$this->textLink = new TextLinkBusiness(
$this->createMock(LoggerInterface::class)
);
}

public function testCanBeParsed() {
self::assertTrue($this->textLink->canBeParsed(null));
self::assertTrue($this->textLink->canBeParsed(''));
self::assertFalse($this->textLink->canBeParsed('null'));
self::assertFalse($this->textLink->canBeParsed('invalidurl'));

self::assertTrue($this->textLink->canBeParsed('https://nextcloud.com'));

self::assertTrue($this->textLink->canBeParsed('test (https://nextcloud.com)'));
self::assertTrue($this->textLink->canBeParsed('https://nextcloud.com (https://nextcloud.com)'));

$column = new Column();
self::assertFalse($this->textLink->canBeParsed(json_encode([
'unknown' => 'https://nextcloud.com'
]), $column));
self::assertTrue($this->textLink->canBeParsed(json_encode([
'resourceUrl' => 'https://nextcloud.com'
]), $column));
self::assertTrue($this->textLink->canBeParsed(json_encode([
'value' => 'https://nextcloud.com'
]), $column));
}

public function testParseValue() {
self::assertEquals('', $this->textLink->parseValue(null));
self::assertEquals('', $this->textLink->parseValue(''));
self::assertEquals('', $this->textLink->parseValue('null'));

self::assertEquals(json_encode(json_encode([
'title' => 'https://nextcloud.com',
'value' => 'https://nextcloud.com',
'providerId' => 'url',
])), $this->textLink->parseValue('https://nextcloud.com'));

self::assertEquals(json_encode(json_encode([
'title' => 'https://nextcloud.com',
'value' => 'https://nextcloud.com',
'providerId' => 'url',
])), $this->textLink->parseValue('https://nextcloud.com (https://nextcloud.com)'));
self::assertEquals(json_encode(json_encode([
'title' => 'test',
'value' => 'https://nextcloud.com',
'providerId' => 'url',
])), $this->textLink->parseValue('test (https://nextcloud.com)'));

$column = new Column();
self::assertEquals('', $this->textLink->parseValue(json_encode([
'unknown' => 'https://nextcloud.com'
]), $column));
self::assertEquals(json_encode(json_encode([
'title' => 'https://nextcloud.com',
'value' => 'https://nextcloud.com',
'providerId' => 'url',
])), $this->textLink->parseValue(json_encode([
'resourceUrl' => 'https://nextcloud.com'
]), $column));
self::assertEquals(json_encode(json_encode([
'title' => 'Test link',
'value' => 'https://nextcloud.com',
'providerId' => 'url',
])), $this->textLink->parseValue(json_encode([
'title' => 'Test link',
'value' => 'https://nextcloud.com',
'providerId' => 'url',
]), $column));
}
}

0 comments on commit 36ae10d

Please sign in to comment.