From e3d30763dabdf12f961ed3d1d7cf4eaee44c65a9 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Sat, 6 Jan 2024 16:34:38 +0000 Subject: tests: Integrate the DB in "unit" tests. --- tests/unit/includes/AccountTest.php | 12 ++++++++++++ tests/unit/includes/PhotodriverTest.php | 28 ++++++---------------------- 2 files changed, 18 insertions(+), 22 deletions(-) create mode 100644 tests/unit/includes/AccountTest.php (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/AccountTest.php b/tests/unit/includes/AccountTest.php new file mode 100644 index 000000000..d123a0c70 --- /dev/null +++ b/tests/unit/includes/AccountTest.php @@ -0,0 +1,12 @@ +assertNotFalse($account); + $this->assertEquals($this->fixtures['account'][0]['account_email'], $account['account_email']); + } +} diff --git a/tests/unit/includes/PhotodriverTest.php b/tests/unit/includes/PhotodriverTest.php index 6f6ad0ffe..34dc058b7 100644 --- a/tests/unit/includes/PhotodriverTest.php +++ b/tests/unit/includes/PhotodriverTest.php @@ -2,38 +2,22 @@ namespace Zotlabs\Tests\Unit\includes; -//use Zotlabs\Photo\PhotoGd; use Zotlabs\Tests\Unit\UnitTestCase; -//use phpmock\phpunit\PHPMock; /** * @brief Unit Test cases for include/photo/photo_driver.php file. */ class PhotodriverTest extends UnitTestCase { - //use PHPMock; public function testPhotofactoryReturnsNullForUnsupportedType() { - // php-mock can not mock global functions which is called by a global function. - // If the calling function is in a namespace it would work. - //$logger = $this->getFunctionMock(__NAMESPACE__, 'logger'); - //$logger->expects($this->once()); - - //$ph = \photo_factory('', 'image/bmp'); - //$this->assertNull($ph); - - $this->markTestIncomplete('Need to mock logger(), otherwise not unit testable.'); + $photo = \photo_factory('', 'image/bmp'); + $this->assertNull($photo); } public function testPhotofactoryReturnsPhotogdIfConfigIgnore_imagickIsSet() { - // php-mock can not mock global functions which is called by a global function. - // If the calling function is in a namespace it would work. - //$gc = $this->getFunctionMock(__NAMESPACE__, 'get_config'); - // simulate get_config('system', 'ignore_imagick') configured - //$gc->expects($this->once())->willReturn(1) - - //$ph = \photo_factory(file_get_contents('images/hz-16.png'), 'image/png'); - //$this->assertInstanceOf(PhotoGd::class, $ph); + \Zotlabs\Lib\Config::Set('system', 'ignore_imagick', true); - $this->markTestIncomplete('Need to mock get_config(), otherwise not unit testable.'); + $photo = \photo_factory(file_get_contents('images/hz-16.png'), 'image/png'); + $this->assertInstanceOf('Zotlabs\Photo\PhotoGd', $photo); } -} \ No newline at end of file +} -- cgit v1.2.3 From f01676085101e2687d15ddd1290cc22cfbfdc150 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Mon, 8 Jan 2024 14:06:53 +0100 Subject: tests: Add config fixtures. Adds fixtures for the config table: - Disables dns checking globally for the tests. - Adds a few disallowed email domains and addresses. --- tests/unit/includes/dba/_files/config.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/unit/includes/dba/_files/config.yml (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/dba/_files/config.yml b/tests/unit/includes/dba/_files/config.yml new file mode 100644 index 000000000..80b9ba12f --- /dev/null +++ b/tests/unit/includes/dba/_files/config.yml @@ -0,0 +1,13 @@ +--- +config: + - + id: 1 + cat: system + k: do_not_check_dns + v: true + - + id: 2 + cat: system + k: not_allowed_email + v: 'baduser@example.com,baddomain.com,*.evil.org' + -- cgit v1.2.3 From 16cd8caef3336d88ebf6dc77e7281968a9380859 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Sun, 7 Jan 2024 19:16:30 +0100 Subject: tests: Add tests for check_account_email --- tests/unit/includes/AccountTest.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/AccountTest.php b/tests/unit/includes/AccountTest.php index d123a0c70..af5bcd3c1 100644 --- a/tests/unit/includes/AccountTest.php +++ b/tests/unit/includes/AccountTest.php @@ -9,4 +9,26 @@ class AccountTest extends Zotlabs\Tests\Unit\UnitTestCase { $this->assertNotFalse($account); $this->assertEquals($this->fixtures['account'][0]['account_email'], $account['account_email']); } + + /** + * Test the `check_account_email` function. + * + * @dataProvider check_account_email_provider + */ + public function test_check_account_email(string $email, array $expected) { + $this->assertEquals($expected, check_account_email($email)); + } + + function check_account_email_provider() : array { + return [ + // Empty and valid emails return the same result + ['', ['error' => false, 'message' => '']], + ['newuser@example.com', ['error' => false, 'message' => '']], + + // Check emails not valid for various readons + ['not_an_email', ['error' => true, 'message' => 'The provided email address is not valid']], + ['baduser@example.com', ['error' => true, 'message' => 'The provided email domain is not among those allowed on this site']], + ['hubzilla@example.com', ['error' => true, 'message' => 'The provided email address is already registered at this site']], + ]; + } } -- cgit v1.2.3 From f71033b30dc20c67e6ed336178d1ac0144ea5c8a Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Mon, 15 Jan 2024 19:11:25 +0100 Subject: tests: Remove id from db fixtures. It seems that PostgreSQL will not update the autoincrement index of the table when inserting rows with an id set. Later inserts without an id set will then fail, because they get assigned an id that already exists. MySQL seems to handle this just fine. Why the id column was added in the first place, one may wonder, but that's how it were. In any case, this broke the PostgreSQL tests in the gitlab CI environment. (While it mysteriously worked in my local ddev environment.) Anyways, the id column is not needed, and things work better without them. --- tests/unit/includes/dba/_files/config.yml | 2 -- 1 file changed, 2 deletions(-) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/dba/_files/config.yml b/tests/unit/includes/dba/_files/config.yml index 80b9ba12f..a8034f2de 100644 --- a/tests/unit/includes/dba/_files/config.yml +++ b/tests/unit/includes/dba/_files/config.yml @@ -1,12 +1,10 @@ --- config: - - id: 1 cat: system k: do_not_check_dns v: true - - id: 2 cat: system k: not_allowed_email v: 'baduser@example.com,baddomain.com,*.evil.org' -- cgit v1.2.3 From ecd4754f6d904158606b39ce40af3d834e4550e0 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Mon, 15 Jan 2024 19:25:09 +0100 Subject: tests: Enable debug logging during tests The debug log will be stored in the test/results directory, and archived as part of the artifacts of the CI run. This should make it easier to get some debugging info out from the CI runs if they fail. --- tests/unit/includes/dba/_files/config.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/dba/_files/config.yml b/tests/unit/includes/dba/_files/config.yml index a8034f2de..e93486857 100644 --- a/tests/unit/includes/dba/_files/config.yml +++ b/tests/unit/includes/dba/_files/config.yml @@ -8,4 +8,16 @@ config: cat: system k: not_allowed_email v: 'baduser@example.com,baddomain.com,*.evil.org' + - + cat: system + k: debugging + v: true + - + cat: system + k: loglevel + v: 2 + - + cat: system + k: logfile + v: tests/results/unit_test.log -- cgit v1.2.3 From 403539919a9a5b1e3e2ac9725a3b8b17403b2935 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Mon, 8 Jan 2024 11:16:45 +0100 Subject: Improve the validate_email function The validate_email function relied on doing an actual domain lookup (on supported platforms) to validate the domain of the email address. This does not work too well in testing environments where we may not want to spam the DNS system, if it at all is available. Apart from the the function did very little to actually verify that it was a valid email address. This patch tries to change that by usng a somewhat stricted regex based validation. While this may not be perfect, it should be good enough in the vast majority of cases. For platforms where no validation was performed with the old version, it will at least be an improvement. Also, it allows testing without having an external network connection. Also clarify the doc comment, that it does not actually try to resolve the email address, just the domain. --- tests/unit/includes/NetworkTest.php | 89 ++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 25 deletions(-) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/NetworkTest.php b/tests/unit/includes/NetworkTest.php index 0b9b42e00..9fb00e9d3 100644 --- a/tests/unit/includes/NetworkTest.php +++ b/tests/unit/includes/NetworkTest.php @@ -5,29 +5,68 @@ * @package test.util */ -use PHPUnit\Framework\TestCase; - -require_once('include/network.php'); - -class NetworkTest extends TestCase { - - public function setup() : void { - \App::set_baseurl("https://mytest.org"); - } - - /** - * @dataProvider localUrlTestProvider - */ - public function testIsLocalURL($url, $expected) { - $this->assertEquals($expected, is_local_url($url)); - } - - public function localUrlTestProvider() : array { - return [ - [ '/some/path', true ], - [ 'https://mytest.org/some/path', true ], - [ 'https://other.site/some/path', false ], - ]; - } -} +class NetworkTest extends Zotlabs\Tests\Unit\UnitTestCase { + + public function setUp() : void { + parent::setUp(); + + \App::set_baseurl("https://mytest.org"); + } + + /** + * @dataProvider localUrlTestProvider + */ + public function testIsLocalURL($url, $expected) { + $this->assertEquals($expected, is_local_url($url)); + } + + public function localUrlTestProvider() : array { + return [ + [ '/some/path', true ], + [ 'https://mytest.org/some/path', true ], + [ 'https://other.site/some/path', false ], + ]; + } + + /** + * Test the validate_email function. + * + * @dataProvider validate_email_provider + */ + public function test_validate_email(string $email, bool $expected) : void { + $this->assertEquals($expected, validate_email($email)); + } + /** + * Test that the validate_email function is disabled when configured to. + * + * @dataProvider validate_email_provider + */ + public function test_disable_validate_email(string $email) : void { + \Zotlabs\Lib\Config::Set('system', 'disable_email_validation', true); + $this->assertTrue(validate_email($email)); + } + + function validate_email_provider() : array { + return [ + // First some invalid email addresses + ['', false], + ['not_an_email', false], + ['@not_an_email', false], + ['not@an@email', false], + ['not@an@email.com', false], + + // then test valid addresses too + ['test@example.com', true], + + // Should also work with international domains + ['some.email@dømain.net', true], + + // Should also work with the new top-level domains + ['some.email@example.cancerresearch', true], + + // And internationalized TLD's + ['some.email@example.شبكة', true] + ]; + } +} -- cgit v1.2.3 From 1881029040245bb5b097ccdc3da64ef7581e9169 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Tue, 6 Feb 2024 11:41:37 +0100 Subject: Clean up markdowntest and fix bb to markdown test. --- tests/unit/includes/MarkdownTest.php | 66 ++++++++++++++---------------------- 1 file changed, 25 insertions(+), 41 deletions(-) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/MarkdownTest.php b/tests/unit/includes/MarkdownTest.php index 953305074..25c947824 100644 --- a/tests/unit/includes/MarkdownTest.php +++ b/tests/unit/includes/MarkdownTest.php @@ -1,30 +1,29 @@ assertEquals($markdown, html2markdown($html)); } - public function html2markdownProvider() { + public function html2markdownProvider(): array { return [ 'empty text' => [ '', @@ -125,23 +122,10 @@ class MarkdownTest extends UnitTestCase { ]; } - /*public function testHtml2markdownException() { - //$this->expectException(\InvalidArgumentException::class); - // need to stub logger() for this to work - $this->assertEquals('', html2markdown('<getFunctionMock(__NAMESPACE__, "bbcode"); - $bbc->expects($this->once())->willReturn('testbold
i
  • li1
  • li2

'); + public function test_bb_to_markdown(): void { + $input = "test[b]bold[/b]\n[i]i[/i][ul][li]li1[/li][li]li2[/li][/ul]\n"; + $expected = "test**bold** \n*i*\n\n- li1\n- li2"; - $this->assertEquals($bb1, bb2diaspora($html1)); + $this->assertEquals($expected, bb_to_markdown($input)); } -*/ } -- cgit v1.2.3 From eb6a143fffba5a796945a425b289e95f7bd28d00 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Tue, 6 Feb 2024 16:19:30 +0100 Subject: Add some tests for markdown to bbcode conversion. --- tests/unit/includes/MarkdownTest.php | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/MarkdownTest.php b/tests/unit/includes/MarkdownTest.php index 25c947824..71f13cdb0 100644 --- a/tests/unit/includes/MarkdownTest.php +++ b/tests/unit/includes/MarkdownTest.php @@ -31,6 +31,43 @@ require_once 'include/markdown.php'; * @brief Unit Test case for markdown functions. */ class MarkdownTest extends UnitTestCase { + + /** + * @dataProvider markdown_to_bbcode_provider + */ + public function test_markdown_to_bbcode(string $expected, string $src): void { + $this->assertEquals($expected, markdown_to_bb($src)); + } + + private function markdown_to_bbcode_provider(): array { + return [ + 'empty text' => [ + '', + '' + ], + 'plain text' => [ + 'This is a test', + 'This is a test' + ], + 'bold and italic' => [ + 'This is a test of [b]bold text[/b], [i]italic text[/i] and [b][i]bold and italic text[/i][/b]', + 'This is a test of **bold text**, *italic text* and ***bold and italic text***' + ], + 'multiline text' => [ + 'This text is text wrapped over multiple lines.', + "This text is\ntext wrapped\nover multiple\nlines." + ], + 'paragraphs' => [ + "Paragraph one\n\nParagraph two", + "Paragraph one\n\nParagraph two", + ], + 'inline image' => [ + '[img=https://example.com/image.jpg]https://example.com/image.jpg[/img]', + '![](https://example.com/image.jpg)' + ], + ]; + } + /** * @covers ::html2markdown * @dataProvider html2markdownProvider -- cgit v1.2.3 From 983f063d33efbf2c6fb43c3aa12562b464b2cb9c Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Tue, 6 Feb 2024 16:23:39 +0100 Subject: Fix image with alt text for html/md to bbcode --- tests/unit/includes/BBCodeTest.php | 46 ++++++++++++++++++++++++++++++++++++ tests/unit/includes/MarkdownTest.php | 4 ++++ 2 files changed, 50 insertions(+) create mode 100644 tests/unit/includes/BBCodeTest.php (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/BBCodeTest.php b/tests/unit/includes/BBCodeTest.php new file mode 100644 index 000000000..9e9b1a33b --- /dev/null +++ b/tests/unit/includes/BBCodeTest.php @@ -0,0 +1,46 @@ +assertEquals($expected, html2bbcode($src)); + } + + private function html2bbcode_provider(): array { + return [ + 'image with alt text' => [ + 'Alt text', + '[img=https://example.com/image.jpg]Alt text[/img]' + ], + ]; + } +} diff --git a/tests/unit/includes/MarkdownTest.php b/tests/unit/includes/MarkdownTest.php index 71f13cdb0..e05cec6fb 100644 --- a/tests/unit/includes/MarkdownTest.php +++ b/tests/unit/includes/MarkdownTest.php @@ -65,6 +65,10 @@ class MarkdownTest extends UnitTestCase { '[img=https://example.com/image.jpg]https://example.com/image.jpg[/img]', '![](https://example.com/image.jpg)' ], + 'inline image with alt text' => [ + '[img=https://example.com/image.jpg]Alt text[/img]', + '![Alt text](https://example.com/image.jpg)' + ], ]; } -- cgit v1.2.3 From ec19ee9d82a9d06e5b86fcb58329767226b0676f Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Tue, 6 Feb 2024 18:39:51 +0100 Subject: Fix convert code blocs from markdown/html to bbcode --- tests/unit/includes/BBCodeTest.php | 4 ++++ tests/unit/includes/MarkdownTest.php | 8 ++++++++ 2 files changed, 12 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/BBCodeTest.php b/tests/unit/includes/BBCodeTest.php index 9e9b1a33b..54c35e67d 100644 --- a/tests/unit/includes/BBCodeTest.php +++ b/tests/unit/includes/BBCodeTest.php @@ -41,6 +41,10 @@ class BBCodeTest extends UnitTestCase { 'Alt text', '[img=https://example.com/image.jpg]Alt text[/img]' ], + 'code block' => [ + "
some\ncode
", + "[code]some\ncode[/code]" + ], ]; } } diff --git a/tests/unit/includes/MarkdownTest.php b/tests/unit/includes/MarkdownTest.php index e05cec6fb..8025e8efa 100644 --- a/tests/unit/includes/MarkdownTest.php +++ b/tests/unit/includes/MarkdownTest.php @@ -69,6 +69,14 @@ class MarkdownTest extends UnitTestCase { '[img=https://example.com/image.jpg]Alt text[/img]', '![Alt text](https://example.com/image.jpg)' ], + 'inline code' => [ + '[code]some code[/code]', + '`some code`' + ], + 'code block no language' => [ + "[code]some code\nover multiple lines[/code]", + "```\nsome code\nover multiple lines\n```" + ], ]; } -- cgit v1.2.3 From e6ce2885c0b4586a270e0ace79598a92365df56f Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Tue, 6 Feb 2024 21:23:51 +0100 Subject: Fix: Keep indentation in html and md code blocks. Moves the logic for unwrapping broken lines in html (and Markdown) to the node processing, instead of doing it over the full html content. This allows us to skip if for code blocks (aka `` elements within `
` elements).
---
 tests/unit/includes/BBCodeTest.php   | 8 ++++++++
 tests/unit/includes/MarkdownTest.php | 4 ++++
 2 files changed, 12 insertions(+)

(limited to 'tests/unit/includes')

diff --git a/tests/unit/includes/BBCodeTest.php b/tests/unit/includes/BBCodeTest.php
index 54c35e67d..035bcbdc7 100644
--- a/tests/unit/includes/BBCodeTest.php
+++ b/tests/unit/includes/BBCodeTest.php
@@ -37,6 +37,10 @@ class BBCodeTest extends UnitTestCase {
 
 	private function html2bbcode_provider(): array {
 		return [
+			'paragraph over multiple lines' => [
+				"

A paragraph over\nmultiple lines\nshould be unwrapped

", + 'A paragraph over multiple lines should be unwrapped' + ], 'image with alt text' => [ 'Alt text', '[img=https://example.com/image.jpg]Alt text[/img]' @@ -45,6 +49,10 @@ class BBCodeTest extends UnitTestCase { "
some\ncode
", "[code]some\ncode[/code]" ], + 'code block with indentation' => [ + "
some\n    indented\ncode
", + "[code]some\n indented\ncode[/code]" + ], ]; } } diff --git a/tests/unit/includes/MarkdownTest.php b/tests/unit/includes/MarkdownTest.php index 8025e8efa..c51fbfe16 100644 --- a/tests/unit/includes/MarkdownTest.php +++ b/tests/unit/includes/MarkdownTest.php @@ -77,6 +77,10 @@ class MarkdownTest extends UnitTestCase { "[code]some code\nover multiple lines[/code]", "```\nsome code\nover multiple lines\n```" ], + 'code block no language indented' => [ + "[code]some code\n over multiple lines\n with indentation[/code]", + "```\nsome code\n over multiple lines\n with indentation\n```" + ], ]; } -- cgit v1.2.3 From 86e953f49566a0f4bb2220a8e5f4013044f4a49f Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Wed, 7 Feb 2024 22:34:13 +0100 Subject: Fix: Preserve hard linebreaks from markdown and html --- tests/unit/includes/MarkdownTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/MarkdownTest.php b/tests/unit/includes/MarkdownTest.php index c51fbfe16..87cfc2899 100644 --- a/tests/unit/includes/MarkdownTest.php +++ b/tests/unit/includes/MarkdownTest.php @@ -57,6 +57,10 @@ class MarkdownTest extends UnitTestCase { 'This text is text wrapped over multiple lines.', "This text is\ntext wrapped\nover multiple\nlines." ], + 'text with hard linebreak' => [ + "Line one\nLine two", + "Line one \nLine two" + ], 'paragraphs' => [ "Paragraph one\n\nParagraph two", "Paragraph one\n\nParagraph two", @@ -73,6 +77,10 @@ class MarkdownTest extends UnitTestCase { '[code]some code[/code]', '`some code`' ], + 'inline code with wrapped text' => [ + '[code]some code unwrapped[/code]', + "`some code\n unwrapped`" + ], 'code block no language' => [ "[code]some code\nover multiple lines[/code]", "```\nsome code\nover multiple lines\n```" -- cgit v1.2.3 From 19ae8cfdfc27578a5f4660993702320ad1e5fac0 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Thu, 8 Feb 2024 10:00:12 +0100 Subject: Support code blocks with language in markdown and html. --- tests/unit/includes/MarkdownTest.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/MarkdownTest.php b/tests/unit/includes/MarkdownTest.php index 87cfc2899..960c15139 100644 --- a/tests/unit/includes/MarkdownTest.php +++ b/tests/unit/includes/MarkdownTest.php @@ -89,6 +89,10 @@ class MarkdownTest extends UnitTestCase { "[code]some code\n over multiple lines\n with indentation[/code]", "```\nsome code\n over multiple lines\n with indentation\n```" ], + 'code block with language' => [ + "[code=php]<?php\necho phpinfo();[/code]", + "```php\n Date: Tue, 13 Feb 2024 13:01:09 +0000 Subject: Add test for a paragraph with a mention and some text --- tests/unit/includes/BBCodeTest.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/BBCodeTest.php b/tests/unit/includes/BBCodeTest.php index 035bcbdc7..9fb7ffc2d 100644 --- a/tests/unit/includes/BBCodeTest.php +++ b/tests/unit/includes/BBCodeTest.php @@ -53,6 +53,10 @@ class BBCodeTest extends UnitTestCase { "
some\n    indented\ncode
", "[code]some\n indented\ncode[/code]" ], + 'paragraph with a mention and some text' => [ + '

@profile some content

', + '[url=https://example.org/@profile]@profile[/url] some content' + ] ]; } } -- cgit v1.2.3 From b7bc28c33356e95f4d45a7d5d2585e67ebd04648 Mon Sep 17 00:00:00 2001 From: Mario Date: Tue, 20 Feb 2024 15:09:11 +0000 Subject: update test --- tests/unit/includes/TextTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/TextTest.php b/tests/unit/includes/TextTest.php index 97fa64895..b76b15dcf 100644 --- a/tests/unit/includes/TextTest.php +++ b/tests/unit/includes/TextTest.php @@ -30,7 +30,7 @@ empty line above'; $this->assertEquals('Your HTML parser does not support HTML5 audio.', purify_html('')); // preserve f6 and bootstrap additional data attributes from our own configuration - $this->assertEquals('
text
', purify_html('
text
')); + $this->assertEquals('
text
', purify_html('
text
')); $this->assertEquals('
  • item1
', purify_html('
  • item1
')); $this->assertEquals('
  • item1
', purify_html('
  • item1
')); } -- cgit v1.2.3 From 25dbc8a9f69ea33a489d94bb69705297664550c2 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Mon, 29 Jan 2024 14:30:52 +0100 Subject: include/dba: Make Dba driver transaction aware. This patch introduced database transaction support to the Dba driver via the DbaTransaction class. The goal of this is to allow the driver control over the creation and finalization of database transactions. Until now code that has needed transaction support has done so directly by issuing "BEGIN", "ROLLBACK" and "COMMIT" commands to the underlying database directly. This has several disadvantages: - We do have no control or knowledge of whether any transactions being active. - Since transactions can not be nested, we run the risk of unrelated code trying to create a transaction when one is already active. - Code using transactions are not testable, as the test runner wraps all tests within a transaction to begin with. This patch should eliminate all these problems. A transaction is started by instantiating the DbaTransaction class: $my_transaction = new \DbaTransaction(); The transaction will automatically be _rolled back_ if it has not been committed before the instance is destroyed. (When the variable holding it goes out of scope, i.e when the containing function returns.) A transaction is committed like this: $my_transaction->commit(); This will immediately commit the changes in the transaction, and the transaction will be marked as committed, so it will not be attempted to be rolled back on destruction. I have chosen to "ignore" the problem of nested transactions by having the DbaTransaction class _not_ initiate a new transaction if one is already active. This also makes the rollback and commit actions of the DbaTransaction class into no-ops. An alternative would be to simulate nested transactions by using save points if a transaction is already active. However, I'm unsure about wether there's any safe way to avoid all potential pitfalls when doing that. In any case, nested transactions should preferably be avoided, and afaict we don't rely on that in any of the existing code. The reason we need to support it in some way is that it's needed for testing where the code under test is creating a transaction on it's own. (Since each test is run within a db transaction to begin with.) Also, I have taken the liberty to assume a PDO based db driver for this stuff. I don't think that's going to be a problem, as that's the only thing supported by the rest of the code in any case. --- tests/unit/includes/dba/TransactionTest.php | 207 ++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 tests/unit/includes/dba/TransactionTest.php (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/dba/TransactionTest.php b/tests/unit/includes/dba/TransactionTest.php new file mode 100644 index 000000000..99e3f459d --- /dev/null +++ b/tests/unit/includes/dba/TransactionTest.php @@ -0,0 +1,207 @@ +pdo_stub = $this->createStub(PDO::class); + } + + + /** + * Test that creating a DbaTransaction object initiates a database transaction. + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + public function test_transaction_initialized_on_construction(): void { + // Stub PDO::inTransaction() + // Expect that it's called once, and return false to simulate that no + // transactions are active. + $this->pdo_stub + ->expects($this->once()) + ->method('inTransaction') + ->willReturn(false); + + // Stub PDO::beginTransaction to ensure that it is being called. + $this->pdo_stub + ->expects($this->once()) + ->method('beginTransaction') + ->willReturn(true); + + $dba = new FakeDba($this->pdo_stub); + + $transaction = new DbaTransaction($dba); + } + + /** + * Test that a transaction is rolled back when the DbaTransaction object + * is destroyed. + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + public function test_uncommitted_transaction_is_rolled_back_on_destruction(): void { + // Stub PDO::inTransaction() + // Expect that it's called once, and return false to simulate that no + // transactions are active. + $this->pdo_stub + ->expects($this->once()) + ->method('inTransaction') + ->willReturn(false); + + // Stub PDO::beginTransaction to ensure that it is being called. + $this->pdo_stub + ->expects($this->once()) + ->method('beginTransaction') + ->willReturn(true); + + // Stub PDO::rollBack to make sure we test it is being called. + $this->pdo_stub + ->expects($this->once()) + ->method('rollBack') + ->willReturn(true); + + $dba = new FakeDba($this->pdo_stub); + + $transaction = new DbaTransaction($dba); + } + + /** + * Test that a committed transaction is not rolled back when the + * DbaTransaction object goes out of scope. + */ + public function test_committed_transaction_is_not_rolled_back(): void { + // Stub PDO::inTransaction() + // Return false to simulate that no transaction is active when called. + $this->pdo_stub + ->expects($this->once()) + ->method('inTransaction') + ->willReturn(false); + + // Stub PDO::beginTransaction to ensure that it is being called. + $this->pdo_stub + ->expects($this->once()) + ->method('beginTransaction') + ->willReturn(true); + + // Stub PDO::rollBack to ensure it is _not_ called + $this->pdo_stub + ->expects($this->never()) + ->method('rollBack'); + + // Stub PDO::commit to make the test check that it is being called + $this->pdo_stub + ->expects($this->once()) + ->method('commit') + ->willReturn(true); + + $dba = new FakeDba($this->pdo_stub); + + $transaction = new DbaTransaction($dba); + $transaction->commit(); + } + + /** + * Test that commiting a transaction more than once is a no-op. + */ + public function test_that_committing_an_already_committed_transaction_does_nothing(): void { + // Stub PDO::inTransaction() + // Return false to simulate that no transaction is active when called. + $this->pdo_stub + ->expects($this->once()) + ->method('inTransaction') + ->willReturn(false); + + // Stub PDO::beginTransaction to ensure that it is being called. + $this->pdo_stub + ->expects($this->once()) + ->method('beginTransaction') + ->willReturn(true); + + // Stub PDO::rollBack to ensure it is _not_ called + $this->pdo_stub + ->expects($this->never()) + ->method('rollBack'); + + // Stub PDO::commit to make the test check that it is being called + $this->pdo_stub + ->expects($this->once()) + ->method('commit') + ->willReturn(true); + + $dba = new FakeDba($this->pdo_stub); + + $transaction = new DbaTransaction($dba); + $transaction->commit(); + $transaction->commit(); + } + + /** + * Test simulating constructing a DbaTransaction object when a transaction + * is already active. + * + * This should _not_ initiate an actual DB transaction, not call the rollBack + * method on destruction. + * + * @SuppressWarnings(PHPMD.UnusedLocalVariable) + */ + public function test_that_nesting_a_transaction_does_not_create_a_new_transaction_in_db(): void { + // Stub PDO::inTransaction() + // We simulate that a transaction is already active, by returning true from + // this method. + $this->pdo_stub + ->expects($this->once()) + ->method('inTransaction') + ->willReturn(true); + + // Stub PDO::beginTransaction + // Since a transaction is already active, we should _not_ initiate + // a new transaction when the DbaTransaction object is constructed. + $this->pdo_stub + ->expects($this->never()) + ->method('beginTransaction'); + + // Stub PDO::rollBack to ensure it is _not_ called + $this->pdo_stub + ->expects($this->never()) + ->method('rollBack'); + + $dba = new FakeDba($this->pdo_stub); + + $transaction = new DbaTransaction($dba); + } +} -- cgit v1.2.3 From 80ed2ff89a1c8ec3e59336a913a05d9c0de3c0a3 Mon Sep 17 00:00:00 2001 From: Harald Eilertsen Date: Fri, 1 Mar 2024 16:18:07 +0000 Subject: Add some beginning tests for bbcode, and a bit of refactoring --- tests/unit/includes/BBCodeTest.php | 138 +++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/BBCodeTest.php b/tests/unit/includes/BBCodeTest.php index 9fb7ffc2d..f29eeafd4 100644 --- a/tests/unit/includes/BBCodeTest.php +++ b/tests/unit/includes/BBCodeTest.php @@ -26,6 +26,55 @@ namespace Zotlabs\Tests\Unit\includes; use Zotlabs\Tests\Unit\UnitTestCase; class BBCodeTest extends UnitTestCase { + /** + * Test converting BBCode to HTML + * + * @dataProvider bbcode_to_html_provider + */ + public function test_parsing_bbcode_to_html(string $src, string $expected): void { + $this->assertBBCode($expected, $src); + } + + /** + * Test the `[observer]` BBCode tags. + * + * @dataProvider bbcode_observer_provider + */ + public function test_bbcode_observer(string $src, bool $logged_in, string $lang, string $expected): void { + if ($logged_in) { + \App::$observer = [ + 'xchan_addr' => '', + 'xchan_name' => '', + 'xchan_connurl' => '', + 'xchan_photo_l' => '', + + // port required in xchan url due to bug in get_rpost_path + 'xchan_url' => 'https://example.com:666', + ]; + } else { + \App::$observer = null; + } + + \App::$language = $lang; + + $this->assertBBCode($expected, $src); + } + + /** + * Test parsing the `[channel]` tag. + */ + public function test_bbcode_channel(): void { + $src = '[channel=1]This is only for channels[/channel][channel=0]This is for everyone else[/channel]'; + + // Verify that the right part is shown to users _not_ in a channel + \App::$channel = null; + $this->assertBBCode('This is for everyone else', $src); + + // Now verify that the right part is shown to users _in_ a channel + \App::$channel = [42]; + $this->assertBBCode('This is only for channels', $src); + } + /** * Test converting html to BBCode. * @@ -35,6 +84,95 @@ class BBCodeTest extends UnitTestCase { $this->assertEquals($expected, html2bbcode($src)); } + /** + * Helper method to validate BBCode conversions. + * + * @param string $expected The expected result of the conversion. + * @param string $src The BBCode to be converted. + */ + private function assertBBCode(string $expected, string $src): void { + // Note! We turn off trying to create oembeds, as that will trigger a + // network request when running the test. + $this->assertEquals($expected, bbcode($src, ['tryoembed' => false])); + } + + /** + * Dataprovider for test_parsing_bbcode_to_html. + * + * @SuppressWarnings(PHPMD.UnusedPrivateMethod) + */ + private function bbcode_to_html_provider(): array { + return [ + 'code block' => [ + "[code]\ntestvar = \"this is a test\"\necho \"the message is \$testvar\"\n[/code]", + '
testvar = "this is a test"
echo "the message is $testvar"
', + ], + ]; + } + + /** + * Dataprovider for test_bbcode_observer + * + * @returns an array of arrays with the following fields: + * * `string $src` - The source string to convert + * * `bool $logged_in` - Whether we should test with a logged in user + * * `string $lang` - The language code of the simulated user + * * `string $expected` - The expecte result of the conversion. + * + * @SuppressWarnings(PHPMD.UnusedPrivateMethod) + */ + private function bbcode_observer_provider(): array { + return [ + 'authenticated observer' => [ + '[observer=1]This should be visible[/observer][observer=0]but not this[/observer]', + true, + 'en', + 'This should be visible', + ], + 'unauthenticated observer' => [ + '[observer=1]This should not be visible[/observer][observer=0]but this should be![/observer]', + false, + 'en', + 'but this should be!', + ], + 'authenticated observer.language matching' => [ + '[observer.language=nb]Kun på norsk[/observer][observer.language!=nb]To everybody else[/observer]', + true, + 'nb', + 'Kun på norsk', + ], + 'authenticated observer.language no match' => [ + '[observer.language=nb]Kun på norsk[/observer][observer.language!=nb]To everybody else[/observer]', + true, + 'en', + 'To everybody else', + ], + 'multiple observer blocks' => [ + '[observer=1]This should be visible,[/observer][observer=0] but not this,[/observer][observer=1] and this as well.[/observer]', + true, + 'en', + 'This should be visible, and this as well.', + ], + 'authenticated observer rpost' => [ + '[rpost=a title]This is the body[/rpost]', + true, + 'en', + 'https://example.com:666/rpost?f=&title=a+title&body=This+is+the+body', + ], + 'unauthenticated observer rpost' => [ + '[rpost=a title]This is the body[/rpost]', + false, + 'en', + '', + ], + ]; + } + + /** + * Dataprovider for test_html2bbcode. + * + * @SuppressWarnings(PHPMD.UnusedPrivateMethod) + */ private function html2bbcode_provider(): array { return [ 'paragraph over multiple lines' => [ -- cgit v1.2.3 From 37b22fe542eb8f336c167c982bf458852e8b32b9 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 6 Mar 2024 21:08:46 +0100 Subject: fix unterminated entity reference error when dealing with domxpath and add a test --- tests/unit/includes/BBCodeTest.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/BBCodeTest.php b/tests/unit/includes/BBCodeTest.php index f29eeafd4..0da50f77a 100644 --- a/tests/unit/includes/BBCodeTest.php +++ b/tests/unit/includes/BBCodeTest.php @@ -194,6 +194,10 @@ class BBCodeTest extends UnitTestCase { 'paragraph with a mention and some text' => [ '

@profile some content

', '[url=https://example.org/@profile]@profile[/url] some content' + ], + 'nested tags with ampersand and new line' => [ + "\nfoo & bar", + '[b] [i]foo & bar[/i][/b]' ] ]; } -- cgit v1.2.3 From b3c260a14529c5c797df50eeae0dacaa931436a8 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 20 Mar 2024 09:31:17 +0100 Subject: fix reshares from streams loosing image --- tests/unit/includes/BBCodeTest.php | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/BBCodeTest.php b/tests/unit/includes/BBCodeTest.php index 0da50f77a..6f79c45f4 100644 --- a/tests/unit/includes/BBCodeTest.php +++ b/tests/unit/includes/BBCodeTest.php @@ -198,6 +198,10 @@ class BBCodeTest extends UnitTestCase { 'nested tags with ampersand and new line' => [ "\nfoo & bar", '[b] [i]foo & bar[/i][/b]' + ], + 'html reshares from streams' => [ + '
image/photo shared something
something
', + '[url=https://example.com][img=https://example.com/image.jpg]image/photo[/img][/url] shared something' . "\n" . 'something' ] ]; } -- cgit v1.2.3 From 3de8f5e7de424563cfe521848b2e2d11d100fcc5 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 20 Mar 2024 14:35:43 +0100 Subject: deal with wihitespace issues in tables and lists and add tests --- tests/unit/includes/BBCodeTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/BBCodeTest.php b/tests/unit/includes/BBCodeTest.php index 6f79c45f4..100d28fc4 100644 --- a/tests/unit/includes/BBCodeTest.php +++ b/tests/unit/includes/BBCodeTest.php @@ -107,6 +107,18 @@ class BBCodeTest extends UnitTestCase { "[code]\ntestvar = \"this is a test\"\necho \"the message is \$testvar\"\n[/code]", '
testvar = "this is a test"
echo "the message is $testvar"
', ], + 'list with linebreaks \n' => [ + "some text\n[list]\n[*] item1\n[*] item2\n[/list]\nsome more text", + 'some text
  • item1
  • item2

some more text' + ], + 'list with linebreaks \r' => [ + "some text\r[list]\r[*] item1\r[*] item2\r[/list]\rsome more text", + 'some text
  • item1
  • item2

some more text' + ], + 'list with linebreaks \r\n' => [ + "some text\r\n[list]\r\n[*] item1\r\n[*] item2\r\n[/list]\r\nsome more text", + 'some text
  • item1
  • item2

some more text' + ] ]; } -- cgit v1.2.3 From 371b8440c3a57103bfdfe15373b025ee1f4a73d3 Mon Sep 17 00:00:00 2001 From: Mario Date: Thu, 21 Mar 2024 11:04:03 +0000 Subject: adjust tests after recent commit --- tests/unit/includes/BBCodeTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tests/unit/includes') diff --git a/tests/unit/includes/BBCodeTest.php b/tests/unit/includes/BBCodeTest.php index 100d28fc4..fedd2df06 100644 --- a/tests/unit/includes/BBCodeTest.php +++ b/tests/unit/includes/BBCodeTest.php @@ -109,15 +109,15 @@ class BBCodeTest extends UnitTestCase { ], 'list with linebreaks \n' => [ "some text\n[list]\n[*] item1\n[*] item2\n[/list]\nsome more text", - 'some text
  • item1
  • item2

some more text' + 'some text
  • item1
  • item2
some more text' ], 'list with linebreaks \r' => [ "some text\r[list]\r[*] item1\r[*] item2\r[/list]\rsome more text", - 'some text
  • item1
  • item2

some more text' + 'some text
  • item1
  • item2
some more text' ], 'list with linebreaks \r\n' => [ "some text\r\n[list]\r\n[*] item1\r\n[*] item2\r\n[/list]\r\nsome more text", - 'some text
  • item1
  • item2

some more text' + 'some text
  • item1
  • item2
some more text' ] ]; } -- cgit v1.2.3