aboutsummaryrefslogtreecommitdiffstats
path: root/Tests/Unit/includes
diff options
context:
space:
mode:
Diffstat (limited to 'Tests/Unit/includes')
-rw-r--r--Tests/Unit/includes/FeedutilsTest.php89
-rw-r--r--Tests/Unit/includes/LanguageTest.php164
-rw-r--r--Tests/Unit/includes/MarkdownTest.php147
-rw-r--r--Tests/Unit/includes/PhotodriverTest.php39
-rw-r--r--Tests/Unit/includes/TextTest.php120
-rw-r--r--Tests/Unit/includes/dba/DBATest.php67
-rw-r--r--Tests/Unit/includes/dba/_files/account.yml9
-rw-r--r--Tests/Unit/includes/dba/dba_pdoTest.php189
8 files changed, 824 insertions, 0 deletions
diff --git a/Tests/Unit/includes/FeedutilsTest.php b/Tests/Unit/includes/FeedutilsTest.php
new file mode 100644
index 000000000..e9826a73d
--- /dev/null
+++ b/Tests/Unit/includes/FeedutilsTest.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Zotlabs\Tests\Unit\includes;
+
+use Zotlabs\Tests\Unit\UnitTestCase;
+
+/**
+ * @brief Unit Test case for include/feedutils.php file.
+ */
+class FeedutilsTest extends UnitTestCase {
+
+ public function test_normalise_id() {
+ $this->assertEquals('id', normalise_id('id'));
+ $this->assertEquals('id', normalise_id('X-ZOT:id'));
+ $this->assertEquals('id id2', normalise_id('X-ZOT:id X-ZOT:id2'));
+ $this->assertEmpty(normalise_id(''));
+ }
+
+ public function test_encode_rel_links() {
+ // invalid params return empty array
+ $this->assertEquals([], encode_rel_links('string'));
+ $this->assertEquals([], encode_rel_links([]));
+
+ $b = ['attribs' => ['' => [
+ 'rel' => 'rel_value',
+ 'type' => 'type_value',
+ 'href' => 'href_value',
+ 'length' => 'length_value',
+ 'title' => 'title_value'
+ ]]];
+ $blink1 = ['link1' => $b];
+ $bresult[] = $b['attribs'][''];
+ $this->assertEquals($bresult, encode_rel_links($blink1));
+ }
+
+/* public function test_encode_rel_links_fail() {
+ $a = [ 'key' => 'value'];
+ $this->assertFalse(encode_rel_links($a));
+ //Illegal string offset 'attribs'
+ }*/
+
+ /**
+ * @uses ::xmlify
+ */
+ public function test_atom_author() {
+ $this->assertEquals('', atom_author('', 'nick', 'name', 'uri', 72, 72, 'png', 'photourl'));
+
+ $a = '<tag>
+ <id>uri</id>
+ <name>nick</name>
+ <uri>uri</uri>
+ <link rel="photo" type="png" media:width="72" media:height="72" href="http://photourl" />
+ <link rel="avatar" type="png" media:width="72" media:height="72" href="http://photourl" />
+ <poco:preferredUsername>nick</poco:preferredUsername>
+ <poco:displayName>name</poco:displayName>
+</tag>';
+
+ $this->assertXmlStringEqualsXmlString($a, atom_author('tag', 'nick', 'name', 'uri', 72, 72, 'png', 'http://photourl'));
+ }
+
+ /**
+ * @uses ::xmlify
+ */
+ public function test_atom_render_author() {
+ $xchan = [
+ 'xchan_addr' => 'chan@hub',
+ 'xchan_url' => 'http://hub',
+ 'xchan_name' => 'Chan',
+ 'xchan_photo_l' => 'http://hub/img',
+ 'xchan_photo_mimetype' => 'mimetype'
+ ];
+ // There is no input validation in atom_render_author
+ //$this->assertEquals('', atom_render_author('', $xchan));
+
+ $a = '<tag>
+ <as:object-type>http://activitystrea.ms/schema/1.0/person</as:object-type>
+ <id>http://hub</id>
+ <name>chan</name>
+ <uri>http://hub</uri>
+ <link rel="alternate" type="text/html" href="http://hub" />
+ <link rel="photo" type="mimetype" media:width="300" media:height="300" href="http://hub/img" />
+ <link rel="avatar" type="mimetype" media:width="300" media:height="300" href="http://hub/img" />
+ <poco:preferredUsername>chan</poco:preferredUsername>
+ <poco:displayName>Chan</poco:displayName>
+</tag>';
+
+ $this->assertXmlStringEqualsXmlString($a, atom_render_author('tag', $xchan));
+ }
+}
diff --git a/Tests/Unit/includes/LanguageTest.php b/Tests/Unit/includes/LanguageTest.php
new file mode 100644
index 000000000..0ca9eacd0
--- /dev/null
+++ b/Tests/Unit/includes/LanguageTest.php
@@ -0,0 +1,164 @@
+<?php
+/*
+ * Copyright (c) 2017 Hubzilla
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+namespace Zotlabs\Tests\Unit\includes;
+
+use Zotlabs\Tests\Unit\UnitTestCase;
+use Text_LanguageDetect;
+//use phpmock\phpunit\PHPMock;
+
+/**
+ * @brief Unit Test cases for include/language.php file.
+ *
+ * @author Klaus Weidenbach
+ */
+class LanguageTest extends UnitTestCase {
+ //use PHPMock;
+
+ /**
+ * @dataProvider languageExamplesProvider
+ * @coversNothing
+ */
+ public function testDetectLanguage($text, $langCode, $confidence) {
+
+ // 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');
+ //$gc->expects($this->once())->willReturn(10)
+ //$cg = $this->getFunctionMock('Zotlabs\Lib\Config', 'Get');
+ //$cg->expects($this->once())->willReturn(10);
+ //$this->assertEquals($langCode, detect_language($text));
+
+
+ // Can not unit test detect_language(), therefore test the used library
+ // only for now to find regressions on library updates.
+ $l = new Text_LanguageDetect;
+ // return 2-letter ISO 639-1 (en) language code
+ $l->setNameMode(2);
+ $lng = $l->detectConfidence($text);
+
+ $this->assertEquals($langCode, $lng['language']);
+ $this->assertEquals($confidence, round($lng['confidence'], 6));
+ }
+
+ public function languageExamplesProvider() {
+ return [
+ 'empty text' => [
+ '',
+ '',
+ null
+ ],
+ 'English' => [
+ 'English is a West Germanic language that was first spoken in early medieval England and is now a global lingua franca.[4][5] Named after the Angles, one of the Germanic tribes that migrated to England, it ultimately derives its name from the Anglia (Angeln) peninsula in the Baltic Sea. It is closely related to the Frisian languages, but its vocabulary has been significantly influenced by other Germanic languages, particularly Norse (a North Germanic language), as well as by Latin and Romance languages, especially French.',
+ 'en',
+ 0.078422
+ ],
+ 'German' => [
+ 'Deutschland ist ein Bundesstaat in Mitteleuropa. Er besteht aus 16 Ländern und ist als freiheitlich-demokratischer und sozialer Rechtsstaat verfasst. Die Bundesrepublik Deutschland stellt die jüngste Ausprägung des deutschen Nationalstaates dar. Mit rund 82,8 Millionen Einwohnern (31. Dezember 2016) zählt Deutschland zu den dicht besiedelten Flächenstaaten.',
+ 'de',
+ 0.134339
+ ],
+ 'Norwegian' => [
+ 'Kongeriket Norge er et nordisk, europeisk land og en selvstendig stat vest på Den skandinaviske halvøy. Landet er langt og smalt, og kysten strekker seg langs Nord-Atlanteren, hvor også Norges kjente fjorder befinner seg. Totalt dekker det relativt tynt befolkede landet 385 000 kvadratkilometer med litt over fem millioner innbyggere (2016).',
+ 'no',
+ 0.007076
+ ]
+ ];
+ }
+
+
+ /**
+ * @covers ::get_language_name
+ * @dataProvider getLanguageNameProvider
+ */
+ public function testGetLanguageName($lang, $name, $trans) {
+ $this->assertEquals($name, get_language_name($lang));
+ foreach ($trans as $k => $v) {
+ //echo "$k -> $v";
+ $this->assertEquals($v, get_language_name($lang, $k));
+ }
+ }
+
+ public function getLanguageNameProvider() {
+ return [
+ 'empty language code' => [
+ '',
+ '',
+ ['de' => '']
+ ],
+ 'invalid language code' => [
+ 'zz',
+ 'zz',
+ ['de' => 'zz']
+ ],
+ 'de' => [
+ 'de',
+ 'German',
+ [
+ 'de' => 'Deutsch',
+ 'nb' => 'tysk'
+ ]
+ ],
+ 'de-de' => [
+ 'de-de',
+ 'German',
+ [
+ 'de-de' => 'Deutsch',
+ 'nb' => 'Deutsch' // should be tysk, seems to be a bug upstream
+ ]
+ ],
+ 'en' => [
+ 'en',
+ 'English',
+ [
+ 'de' => 'Englisch',
+ 'nb' => 'engelsk'
+ ]
+ ],
+ 'en-gb' => [
+ 'en-gb',
+ 'British English',
+ [
+ 'de' => 'Englisch (Vereinigtes Königreich)',
+ 'nb' => 'engelsk (Storbritannia)'
+ ]
+ ],
+ 'en-au' => [
+ 'en-au',
+ 'Australian English',
+ [
+ 'de' => 'Englisch (Australien)',
+ 'nb' => 'engelsk (Australia)'
+ ]
+ ],
+ 'nb' => [
+ 'nb',
+ 'Norwegian Bokmål',
+ [
+ 'de' => 'Norwegisch Bokmål',
+ 'nb' => 'norsk bokmål'
+ ]
+ ]
+ ];
+ }
+}
diff --git a/Tests/Unit/includes/MarkdownTest.php b/Tests/Unit/includes/MarkdownTest.php
new file mode 100644
index 000000000..2a92a58d2
--- /dev/null
+++ b/Tests/Unit/includes/MarkdownTest.php
@@ -0,0 +1,147 @@
+<?php
+/*
+ * Copyright (c) 2017 Hubzilla
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*/
+
+namespace Zotlabs\Tests\Unit\includes;
+
+use Zotlabs\Tests\Unit\UnitTestCase;
+use phpmock\phpunit\PHPMock;
+
+require_once 'include/markdown.php';
+
+/**
+ * @brief Unit Test case for markdown functions.
+ */
+class MarkdownTest extends UnitTestCase {
+ use PHPMock;
+
+ /**
+ * @covers ::html2markdown
+ * @dataProvider html2markdownProvider
+ */
+ public function testHtml2markdown($html, $markdown) {
+ $this->assertEquals($markdown, html2markdown($html));
+ }
+
+ public function html2markdownProvider() {
+ return [
+ 'empty text' => [
+ '',
+ ''
+ ],
+ 'space and nbsp only' => [
+ ' &nbsp;',
+ ''
+ ],
+
+ 'strong, b, em, i, bib' => [
+ '<strong>strong</strong> <b>bold</b> <em>em</em> <i>italic</i> <b>bo<i>italic</i>ld</b>',
+ '**strong** **bold** *em* *italic* **bo*italic*ld**'
+ ],
+
+ 'empty tags' => [
+ 'text1 <b></b> text2 <i></i>',
+ 'text1 text2'
+ ],
+ 'HTML entities, lt does not work' => [
+ '& gt > lt <',
+ '&amp; gt &gt; lt'
+ ],
+ 'escaped HTML entities' => [
+ '&amp; lt &lt; gt &gt;',
+ '&amp; lt &lt; gt &gt;'
+ ],
+ 'linebreak' => [
+ "line1<br>line2\nline3",
+ "line1 \nline2 line3"
+ ],
+ 'headlines' => [
+ '<h1>header1</h1><h3>Header 3</h3>',
+ "header1\n=======\n\n### Header 3"
+ ],
+ 'unordered list' => [
+ '<ul><li>Item 1</li><li>Item 2</li><li>Item <b>3</b></li></ul>',
+ "- Item 1\n- Item 2\n- Item **3**"
+ ],
+ 'ordered list' => [
+ '<ol><li>Item 1</li><li>Item 2</li><li>Item <b>3</b></li></ol>',
+ "1. Item 1\n2. Item 2\n3. Item **3**"
+ ],
+ 'nested lists' => [
+ '<ul><li>Item 1<ol><li>Item 1a</li><li>Item <b>1b</b></ol></li><li>Item 2</li></ul>',
+ "- Item 1\n 1. Item 1a\n 2. Item **1b**\n- Item 2"
+ ],
+ 'img' => [
+ '<img src="/path/to/img.png" alt="alt text" title="title text">',
+ '![alt text](/path/to/img.png "title text")'
+ ],
+ 'link' => [
+ '<a href="http://hubzilla.org" title="Hubzilla">link</a>',
+ '[link](http://hubzilla.org "Hubzilla")'
+ ],
+ 'img link' => [
+ '<a href="http://hubzilla.org" title="Hubzilla"><img src="/img/hubzilla.png" alt="alt img text" title="img title"></a>',
+ '[![alt img text](/img/hubzilla.png "img title")](http://hubzilla.org "Hubzilla")'
+ ],
+ 'script' => [
+ "<script>alert('test');</script>",
+ "<script>alert('test');</script>"
+ ],
+ 'blockquote, issue #793' => [
+ '<blockquote>something</blockquote>blah',
+ "> something\n\nblah"
+ ],
+ 'code' => [
+ '<code>&lt;p&gt;HTML text&lt;/p&gt;</code>',
+ '`<p>HTML text</p>`'
+ ],
+ 'pre' => [
+ '<pre> one line with spaces </pre>',
+ "```\n one line with spaces \n```"
+ ],
+ 'div p' => [
+ '<div>div</div><div><p>p</p></div>',
+ "<div>div</div><div>p\n\n</div>"
+ ]
+ ];
+ }
+
+ /*public function testHtml2markdownException() {
+ //$this->expectException(\InvalidArgumentException::class);
+ // need to stub logger() for this to work
+ $this->assertEquals('', html2markdown('<<invalid'));
+ }*/
+
+/* public function testBB2diasporaMardown() {
+ //stub bbcode() and return our HTML, we just need to test the HTML2Markdown library.
+ $html1 = 'test<b>bold</b><br><i>i</i><ul><li>li1</li><li>li2</li></ul><br>';
+ $bb1 = 'test';
+
+ // php-mock can not mock global functions which is called by a global function.
+ // If the calling function is in a namespace it does work.
+ $bbc = $this->getFunctionMock(__NAMESPACE__, "bbcode");
+ $bbc->expects($this->once())->willReturn('test<b>bold</b><br><i>i</i><ul><li>li1</li><li>li2</li></ul><br>');
+
+ $this->assertEquals($bb1, bb2diaspora($html1));
+ }
+*/
+}
diff --git a/Tests/Unit/includes/PhotodriverTest.php b/Tests/Unit/includes/PhotodriverTest.php
new file mode 100644
index 000000000..6f6ad0ffe
--- /dev/null
+++ b/Tests/Unit/includes/PhotodriverTest.php
@@ -0,0 +1,39 @@
+<?php
+
+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.');
+ }
+
+ 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);
+
+ $this->markTestIncomplete('Need to mock get_config(), otherwise not unit testable.');
+ }
+} \ No newline at end of file
diff --git a/Tests/Unit/includes/TextTest.php b/Tests/Unit/includes/TextTest.php
new file mode 100644
index 000000000..97fa64895
--- /dev/null
+++ b/Tests/Unit/includes/TextTest.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace Zotlabs\Tests\Unit\includes;
+
+use Zotlabs\Tests\Unit\UnitTestCase;
+
+/**
+ * @brief Unit Test case for include/text.php file.
+ *
+ * @author ken restivo
+ */
+class TextTest extends UnitTestCase {
+
+
+ public function testPurifyHTML() {
+ // linebreaks
+ $htmlbr = 'first line<br />
+ one tab preserved
+
+empty line above';
+ $this->assertEquals($htmlbr, purify_html($htmlbr));
+
+ // HTML5 is not supported by HTMLPurifier yet, test our own configuration
+ $html5elements = '<section>section<nav>navigation</nav><article>main<a href="http://hubzilla.org/">hubzilla.org</a></article></section><footer>footer</footer>';
+ $this->assertEquals($html5elements, purify_html($html5elements));
+ $this->assertEquals('<button>button label</button>', purify_html('<button>button label</button>'));
+
+ // unsupported HTML5 elements
+ $this->assertEquals('Your HTML parser does not support HTML5 video.', purify_html('<video controls><source src="movie.ogg" type="video/ogg">Your HTML parser does not support HTML5 video.</video>'));
+ $this->assertEquals('Your HTML parser does not support HTML5 audio.', purify_html('<audio controls><source src="movie.ogg" "type="audio/ogg">Your HTML parser does not support HTML5 audio.</audio>'));
+
+ // preserve f6 and bootstrap additional data attributes from our own configuration
+ $this->assertEquals('<div data-title="title">text</div>', purify_html('<div data-title="title">text</div>'));
+ $this->assertEquals('<ul data-accordion-menu=""><li>item1</li></ul>', purify_html('<ul data-accordion-menu><li>item1</li></ul>'));
+ $this->assertEquals('<ul><li>item1</li></ul>', purify_html('<ul data-accordion-menu-unknown><li>item1</li></ul>'));
+ }
+
+ /**
+ * @covers ::purify_html
+ */
+ public function testPurifyHTML_html() {
+ $this->assertEquals('<div id="id01"><p class="class01">ids und classes</p></div>', purify_html('<div id="id01"><p class="class01">ids und classes</p></div>'));
+ $this->assertEquals('<div><p>close missing tags</p></div>', purify_html('<div><p>close missing tags'));
+ $this->assertEquals('<center>deprecated tag</center>', purify_html('<center>deprecated tag</center>'));
+ $this->assertEquals('<span></span><div>illegal nesting</div>', purify_html('<span><div>illegal nesting</div></span>'));
+ $this->assertEquals('<a href="#">link with target</a>', purify_html('<a href="#" target="_blank">link with target</a>'));
+ $this->assertEquals('<a href="#">link with rel="nofollow"</a>', purify_html('<a href="#" rel="nofollow">link with rel="nofollow"</a>'));
+ $this->assertEquals('a b', purify_html('a&nbsp;b'));
+ $this->assertEquals('ä ä € €', purify_html('ä &auml; &euro; &#8364;'));
+ $this->assertEquals('<img src="picture.png" alt="text" />', purify_html('<img src="picture.png" alt="text">'));
+ $this->assertEquals('', purify_html('<iframe width="560" height="315" src="https://www.youtube.com/embed/kiNGx5oL7hk" frameborder="0" allowfullscreen></iframe>'));
+ }
+
+ /**
+ * @covers ::purify_html
+ */
+ public function testPurifyHTML_js() {
+ $this->assertEquals('<div></div>', purify_html('<div><img src="javascript:evil();" onload="evil();"></div>'));
+ $this->assertEquals('<a href="#">link</a>', purify_html('<a href="#" onclick="alert(\'xss\')">link</a>'));
+ $this->assertEquals('', purify_html('<IMG SRC="javascript:alert(&#039;XSS&#039;);">'));
+ $this->assertEquals('', purify_html('<script>alter("42")</script>'));
+ }
+
+ /**
+ * @covers ::purify_html
+ */
+ public function testPurifyHTML_css() {
+ $this->assertEquals('<p style="color:#FF0000;background-color:#fff;">red</p>', purify_html('<p style="color:red; background-color:#fff">red</p>'));
+ $this->assertEquals('<p>invalid color</p>', purify_html('<p style="color:invalid; background-color:#jjkkmm">invalid color</p>'));
+ $this->assertEquals('<p>invalid style</p>', purify_html('<p style="foo:bar">invalid style</p>'));
+
+ // test our own CSS configuration
+ $this->assertEquals('<div>position removed</div>', purify_html('<div style="position:absolut">position removed</div>'));
+ $this->assertEquals('<div style="position:fixed;">position preserved</div>', purify_html('<div style="position:fixed">position preserved</div>', true));
+ $this->assertEquals('<div>invalid position removed</div>', purify_html('<div style="position:invalid">invalid position removed</div>', true));
+
+ $this->assertEquals('<div>position removed</div>', purify_html('<div style="top:10px; left:3em;">position removed</div>'));
+ $this->assertEquals('<div style="top:10px;left:3em;right:50%;">position preserved</div>', purify_html('<div style="top:10px; left:3em; right:50%;">position preserved</div>', true));
+ $this->assertEquals('<div>invalid position removed</div>', purify_html('<div style="top:10p">invalid position removed</div>', true));
+ }
+
+ /**
+ * @dataProvider notagsProvider
+ */
+ public function testNotags($string, $expected) {
+ $this->assertEquals($expected, notags($string));
+ }
+ public function notagsProvider() {
+ return [
+ 'empty string' => ['', ''],
+ 'simple tag' => ['<value>', '[value]'],
+ 'tag pair' => ['<b>text</b>', '[b]text[/b]'],
+ 'double angle bracket' => ['<<value', '[[value'],
+ 'HTML entity &gt;' => ['&gt;', '&gt;']
+ ];
+ }
+
+ /**
+ * @dataProvider sanitise_aclProvider
+ */
+ public function testSanitise_acl($string, $expected) {
+ sanitise_acl($string);
+ $this->assertEquals($expected, $string);
+ }
+ public function sanitise_aclProvider() {
+ return [
+ 'text' => ['value', '<value>'],
+ 'text with angle bracket' => ['<value>', '<[value]>'],
+ 'comma separated acls' => ['value1,value2', '<value1,value2>']
+ ];
+ }
+
+ public function testUnsetSanitise_acl() {
+ $empty = '';
+ sanitise_acl($empty);
+ $this->assertTrue(isset($empty)); // unset() not working? Would expect false
+ $this->assertEmpty($empty);
+ }
+
+}
diff --git a/Tests/Unit/includes/dba/DBATest.php b/Tests/Unit/includes/dba/DBATest.php
new file mode 100644
index 000000000..900d13083
--- /dev/null
+++ b/Tests/Unit/includes/dba/DBATest.php
@@ -0,0 +1,67 @@
+<?php
+/*
+ * Copyright (c) 2017 Hubzilla
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+namespace Zotlabs\Tests\Unit\includes;
+
+use Zotlabs\Tests\Unit\UnitTestCase;
+
+// required because of process isolation and no autoloading
+require_once 'include/dba/dba_driver.php';
+
+/**
+ * @brief Unit Test case for include/dba/DBA.php file.
+ *
+ * This test needs process isolation because of static \DBA.
+ * @runTestsInSeparateProcesses
+ */
+class DBATest extends UnitTestCase {
+
+ public function testDbaFactoryMysql() {
+ $this->assertNull(\DBA::$dba);
+
+ $ret = \DBA::dba_factory('server', 'port', 'user', 'pass', 'db', '0');
+ $this->assertInstanceOf('dba_pdo', $ret);
+ $this->assertFalse($ret->connected);
+
+ $this->assertSame('mysql', \DBA::$scheme);
+ $this->assertSame('schema_mysql.sql', \DBA::$install_script);
+ $this->assertSame('0001-01-01 00:00:00', \DBA::$null_date);
+ $this->assertSame('UTC_TIMESTAMP()', \DBA::$utc_now);
+ $this->assertSame('`', \DBA::$tquot);
+ }
+
+ public function testDbaFactoryPostgresql() {
+ $this->assertNull(\DBA::$dba);
+
+ $ret = \DBA::dba_factory('server', 'port', 'user', 'pass', 'db', '1');
+ $this->assertInstanceOf('dba_pdo', $ret);
+ $this->assertFalse($ret->connected);
+
+ $this->assertSame('pgsql', \DBA::$scheme);
+ $this->assertSame('schema_postgres.sql', \DBA::$install_script);
+ $this->assertSame('0001-01-01 00:00:00', \DBA::$null_date);
+ $this->assertSame("now() at time zone 'UTC'", \DBA::$utc_now);
+ $this->assertSame('"', \DBA::$tquot);
+ }
+
+}
diff --git a/Tests/Unit/includes/dba/_files/account.yml b/Tests/Unit/includes/dba/_files/account.yml
new file mode 100644
index 000000000..344bdb799
--- /dev/null
+++ b/Tests/Unit/includes/dba/_files/account.yml
@@ -0,0 +1,9 @@
+account:
+ -
+ account_id: 42
+ account_email: "hubzilla@example.com"
+ account_language: "no"
+ -
+ account_id: 43
+ account_email: "hubzilla@example.org"
+ account_language: "de"
diff --git a/Tests/Unit/includes/dba/dba_pdoTest.php b/Tests/Unit/includes/dba/dba_pdoTest.php
new file mode 100644
index 000000000..689f5a7ce
--- /dev/null
+++ b/Tests/Unit/includes/dba/dba_pdoTest.php
@@ -0,0 +1,189 @@
+<?php
+/*
+ * Copyright (c) 2017 Hubzilla
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+namespace Zotlabs\Tests\Unit\includes;
+
+use Zotlabs\Tests\Unit\DatabaseTestCase;
+use PHPUnit\DbUnit\TestCaseTrait;
+use PHPUnit\DbUnit\DataSet\YamlDataSet;
+
+require_once 'include/dba/dba_pdo.php';
+
+/**
+ * @brief Unit Test case for include/dba/dba_pdo.php file.
+ *
+ * Some very basic tests to see if our database layer can connect to a real
+ * database.
+ */
+class dba_pdoTest extends DatabaseTestCase {
+
+ use TestCaseTrait;
+
+ /**
+ * @var \dba_driver
+ */
+ protected $dba;
+
+
+ /**
+ * Set initial state of the database before each test is executed.
+ * Load database fixtures.
+ *
+ * @return \PHPUnit\DbUnit\DataSet\IDataSet
+ */
+ public function getDataSet() {
+ return new YamlDataSet(dirname(__FILE__) . '/_files/account.yml');
+ }
+
+ protected function setUp(): void {
+ // Will invoke getDataSet() to load fixtures into DB
+ parent::setUp();
+
+ $this->dba = new \dba_pdo(
+ \getenv('hz_db_server'),
+ \getenv('hz_db_scheme'),
+ \getenv('hz_db_port'),
+ \getenv('hz_db_user'),
+ \getenv('hz_db_pass'),
+ \getenv('hz_db_database')
+ );
+ }
+ protected function assertPreConditions() {
+ $this->assertSame('pdo', $this->dba->getdriver(), "Driver is expected to be 'pdo'.");
+ $this->assertInstanceOf('dba_driver', $this->dba);
+ $this->assertTrue($this->dba->connected, 'Pre condition failed, DB is not connected.');
+ $this->assertInstanceOf('PDO', $this->dba->db);
+ }
+ protected function tearDown(): void {
+ $this->dba = null;
+ }
+
+
+ /**
+ * @group mysql
+ */
+ public function testQuoteintervalOnMysql() {
+ $this->assertSame('value', $this->dba->quote_interval('value'));
+ }
+ /**
+ * @group postgresql
+ */
+ public function testQuoteintervalOnPostgresql() {
+ $this->assertSame("'value'", $this->dba->quote_interval('value'));
+ }
+
+ /**
+ * @group mysql
+ */
+ public function testGenerateMysqlConcatSql() {
+ $this->assertSame('GROUP_CONCAT(DISTINCT field SEPARATOR \';\')', $this->dba->concat('field', ';'));
+ $this->assertSame('GROUP_CONCAT(DISTINCT field2 SEPARATOR \' \')', $this->dba->concat('field2', ' '));
+ }
+ /**
+ * @group postgresql
+ */
+ public function testGeneratePostgresqlConcatSql() {
+ $this->assertSame('string_agg(field,\';\')', $this->dba->concat('field', ';'));
+ $this->assertSame('string_agg(field2,\' \')', $this->dba->concat('field2', ' '));
+ }
+
+
+ public function testConnectToSqlServer() {
+ // connect() is done in dba_pdo constructor which is called in setUp()
+ $this->assertTrue($this->dba->connected);
+ }
+
+ /**
+ * @depends testConnectToSqlServer
+ */
+ public function testCloseSqlServerConnection() {
+ $this->dba->close();
+
+ $this->assertNull($this->dba->db);
+ $this->assertFalse($this->dba->connected);
+ }
+
+ /**
+ * @depends testConnectToSqlServer
+ */
+ public function testSelectQueryShouldReturnArray() {
+ $ret = $this->dba->q('SELECT * FROM account');
+
+ $this->assertTrue(is_array($ret));
+ }
+
+ /**
+ * @depends testConnectToSqlServer
+ */
+ public function testInsertQueryShouldReturnPdostatement() {
+ // Fixture account.yml adds two entries to account table
+ $this->assertEquals(2, $this->getConnection()->getRowCount('account'), 'Pre-Condition');
+
+ $ret = $this->dba->q('INSERT INTO account
+ (account_id, account_email, account_language)
+ VALUES (100, \'insert@example.com\', \'de\')
+ ');
+ $this->assertInstanceOf('PDOStatement', $ret);
+
+ $this->assertEquals(3, $this->getConnection()->getRowCount('account'), 'Inserting failed');
+ }
+
+
+ public function testConnectToWrongSqlServer() {
+ $nodba = new \dba_pdo('wrongserver',
+ \getenv('hz_db_scheme'), \getenv('hz_db_port'),
+ \getenv('hz_db_user'), \getenv('hz_db_pass'),
+ \getenv('hz_db_database')
+ );
+
+ $this->assertSame('pdo', $nodba->getdriver());
+ $this->assertInstanceOf('dba_pdo', $nodba);
+ $this->assertFalse($nodba->connected);
+ $this->assertNull($nodba->db);
+
+ $this->assertFalse($nodba->q('SELECT * FROM account'));
+ }
+
+ /**
+ * @depends testConnectToSqlServer
+ */
+ public function testSelectQueryToNonExistentTableShouldReturnFalse() {
+ $ret = $this->dba->q('SELECT * FROM non_existent_table');
+
+ $this->assertFalse($ret);
+ }
+
+ /**
+ * @depends testConnectToSqlServer
+ */
+ public function testInsertQueryToNonExistentTableShouldReturnEmptyArray() {
+ $ret = $this->dba->q('INSERT INTO non_existent_table
+ (account_email, account_language)
+ VALUES (\'email@example.com\', \'en\')
+ ');
+
+ $this->assertNotInstanceOf('PDOStatement', $ret);
+ $this->isEmpty($ret);
+ }
+
+}