1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
use Filesystem as SS_Filesystem; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* @package framework |
7
|
|
|
* @subpackage tests |
8
|
|
|
*/ |
9
|
|
|
class HtmlEditorFieldTest extends FunctionalTest { |
10
|
|
|
|
11
|
|
|
protected static $fixture_file = 'HtmlEditorFieldTest.yml'; |
12
|
|
|
|
13
|
|
|
protected static $use_draft_site = true; |
14
|
|
|
|
15
|
|
|
protected $requiredExtensions = array( |
16
|
|
|
'HtmlEditorField_Toolbar' => array('HtmlEditorFieldTest_DummyMediaFormFieldExtension') |
17
|
|
|
); |
18
|
|
|
|
19
|
|
|
protected $extraDataObjects = array('HtmlEditorFieldTest_Object'); |
20
|
|
|
|
21
|
|
View Code Duplication |
public function setUp() { |
|
|
|
|
22
|
|
|
parent::setUp(); |
23
|
|
|
|
24
|
|
|
// Set backend root to /HtmlEditorFieldTest |
25
|
|
|
AssetStoreTest_SpyStore::activate('HtmlEditorFieldTest'); |
26
|
|
|
|
27
|
|
|
// Create a test files for each of the fixture references |
28
|
|
|
$files = File::get()->exclude('ClassName', 'Folder'); |
29
|
|
|
foreach($files as $file) { |
30
|
|
|
$fromPath = BASE_PATH . '/framework/tests/forms/images/' . $file->Name; |
31
|
|
|
$destPath = AssetStoreTest_SpyStore::getLocalPath($file); // Only correct for test asset store |
32
|
|
|
SS_Filesystem::makeFolder(dirname($destPath)); |
33
|
|
|
copy($fromPath, $destPath); |
34
|
|
|
} |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
public function tearDown() { |
38
|
|
|
AssetStoreTest_SpyStore::reset(); |
39
|
|
|
parent::tearDown(); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
public function testBasicSaving() { |
43
|
|
|
$obj = new HtmlEditorFieldTest_Object(); |
44
|
|
|
$editor = new HtmlEditorField('Content'); |
45
|
|
|
|
46
|
|
|
$editor->setValue('<p class="foo">Simple Content</p>'); |
47
|
|
|
$editor->saveInto($obj); |
48
|
|
|
$this->assertEquals('<p class="foo">Simple Content</p>', $obj->Content, 'Attributes are preserved.'); |
49
|
|
|
|
50
|
|
|
$editor->setValue('<p>Unclosed Tag'); |
51
|
|
|
$editor->saveInto($obj); |
52
|
|
|
$this->assertEquals('<p>Unclosed Tag</p>', $obj->Content, 'Unclosed tags are closed.'); |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
public function testNullSaving() { |
56
|
|
|
$obj = new HtmlEditorFieldTest_Object(); |
57
|
|
|
$editor = new HtmlEditorField('Content'); |
58
|
|
|
|
59
|
|
|
$editor->setValue(null); |
60
|
|
|
$editor->saveInto($obj); |
61
|
|
|
$this->assertEquals('', $obj->Content, "Doesn't choke on empty/null values."); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
public function testResizedImageInsertion() { |
65
|
|
|
$obj = new HtmlEditorFieldTest_Object(); |
66
|
|
|
$editor = new HtmlEditorField('Content'); |
67
|
|
|
|
68
|
|
|
$fileID = $this->idFromFixture('Image', 'example_image'); |
69
|
|
|
$editor->setValue(sprintf( |
70
|
|
|
'[image src="assets/HTMLEditorFieldTest_example.jpg" width="10" height="20" id="%d"]', |
71
|
|
|
$fileID |
72
|
|
|
)); |
73
|
|
|
$editor->saveInto($obj); |
74
|
|
|
|
75
|
|
|
$parser = new CSSContentParser($obj->dbObject('Content')->forTemplate()); |
76
|
|
|
$xml = $parser->getByXpath('//img'); |
77
|
|
|
$this->assertEquals( |
78
|
|
|
'HTMLEditorFieldTest example', |
79
|
|
|
(string)$xml[0]['alt'], |
80
|
|
|
'Alt tags are added by default based on filename' |
81
|
|
|
); |
82
|
|
|
$this->assertEquals('', (string)$xml[0]['title'], 'Title tags are added by default.'); |
83
|
|
|
$this->assertEquals(10, (int)$xml[0]['width'], 'Width tag of resized image is set.'); |
84
|
|
|
$this->assertEquals(20, (int)$xml[0]['height'], 'Height tag of resized image is set.'); |
85
|
|
|
|
86
|
|
|
$neededFilename |
87
|
|
|
= '/assets/HtmlEditorFieldTest/f5c7c2f814/HTMLEditorFieldTest-example__ResizedImageWyIxMCIsIjIwIl0.jpg'; |
88
|
|
|
|
89
|
|
|
$this->assertEquals($neededFilename, (string)$xml[0]['src'], 'Correct URL of resized image is set.'); |
90
|
|
|
$this->assertTrue(file_exists(BASE_PATH.DIRECTORY_SEPARATOR.$neededFilename), 'File for resized image exists'); |
91
|
|
|
$this->assertEquals(false, $obj->HasBrokenFile, 'Referenced image file exists.'); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
View Code Duplication |
public function testMultiLineSaving() { |
|
|
|
|
95
|
|
|
$obj = $this->objFromFixture('HtmlEditorFieldTest_Object', 'home'); |
96
|
|
|
$editor = new HtmlEditorField('Content'); |
97
|
|
|
$editor->setValue('<p>First Paragraph</p><p>Second Paragraph</p>'); |
98
|
|
|
$editor->saveInto($obj); |
|
|
|
|
99
|
|
|
$this->assertEquals('<p>First Paragraph</p><p>Second Paragraph</p>', $obj->Content); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
View Code Duplication |
public function testSavingLinksWithoutHref() { |
|
|
|
|
103
|
|
|
$obj = $this->objFromFixture('HtmlEditorFieldTest_Object', 'home'); |
104
|
|
|
$editor = new HtmlEditorField('Content'); |
105
|
|
|
|
106
|
|
|
$editor->setValue('<p><a name="example-anchor"></a></p>'); |
107
|
|
|
$editor->saveInto($obj); |
|
|
|
|
108
|
|
|
|
109
|
|
|
$this->assertEquals ( |
110
|
|
|
'<p><a name="example-anchor"></a></p>', $obj->Content, 'Saving a link without a href attribute works' |
111
|
|
|
); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
public function testGetAnchors() { |
115
|
|
|
if (!class_exists('Page')) { |
116
|
|
|
$this->markTestSkipped(); |
117
|
|
|
} |
118
|
|
|
$html = '<div name="foo"></div> |
119
|
|
|
<div name=\'bar\'></div> |
120
|
|
|
<div id="baz"></div> |
121
|
|
|
<div id=\'bam\'></div> |
122
|
|
|
<div id = "baz"></div> |
123
|
|
|
<div id = ""></div> |
124
|
|
|
<div id="some\'id"></div> |
125
|
|
|
<div id=bar></div>'; |
126
|
|
|
$expected = array( |
127
|
|
|
'foo', |
128
|
|
|
'bar', |
129
|
|
|
'baz', |
130
|
|
|
'bam', |
131
|
|
|
"some'id", |
132
|
|
|
); |
133
|
|
|
$page = new Page(); |
134
|
|
|
$page->Title = 'Test'; |
135
|
|
|
$page->Content = $html; |
136
|
|
|
$page->write(); |
137
|
|
|
$this->useDraftSite(true); |
138
|
|
|
|
139
|
|
|
$request = new SS_HTTPRequest('GET', '/', array( |
140
|
|
|
'PageID' => $page->ID, |
141
|
|
|
)); |
142
|
|
|
|
143
|
|
|
$toolBar = new HtmlEditorField_Toolbar(new Controller(), 'test'); |
144
|
|
|
$toolBar->setRequest($request); |
145
|
|
|
|
146
|
|
|
$results = json_decode($toolBar->getanchors(), true); |
147
|
|
|
$this->assertEquals($expected, $results); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
public function testHtmlEditorFieldFileLocal() { |
151
|
|
|
$file = new HtmlEditorField_Image('http://domain.com/folder/my_image.jpg?foo=bar'); |
152
|
|
|
$this->assertEquals('http://domain.com/folder/my_image.jpg?foo=bar', $file->URL); |
153
|
|
|
$this->assertEquals('my_image.jpg', $file->Name); |
154
|
|
|
$this->assertEquals('jpg', $file->Extension); |
|
|
|
|
155
|
|
|
// TODO Can't easily test remote file dimensions |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
public function testHtmlEditorFieldFileRemote() { |
159
|
|
|
$fileFixture = new File(array('Name' => 'my_local_image.jpg', 'Filename' => 'folder/my_local_image.jpg')); |
160
|
|
|
$file = new HtmlEditorField_Image('http://localdomain.com/folder/my_local_image.jpg', $fileFixture); |
161
|
|
|
$this->assertEquals('http://localdomain.com/folder/my_local_image.jpg', $file->URL); |
162
|
|
|
$this->assertEquals('my_local_image.jpg', $file->Name); |
163
|
|
|
$this->assertEquals('jpg', $file->Extension); |
|
|
|
|
164
|
|
|
} |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* @package framework |
169
|
|
|
* @subpackage tests |
170
|
|
|
*/ |
171
|
|
|
class HtmlEditorFieldTest_DummyMediaFormFieldExtension extends Extension implements TestOnly { |
172
|
|
|
public static $fields = null; |
173
|
|
|
public static $update_called = false; |
174
|
|
|
|
175
|
|
|
public function updateImageForm($form) { |
176
|
|
|
self::$update_called = true; |
177
|
|
|
self::$fields = $form->Fields(); |
178
|
|
|
} |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
class HtmlEditorFieldTest_Object extends DataObject implements TestOnly { |
182
|
|
|
private static $db = array( |
|
|
|
|
183
|
|
|
'Title' => 'Varchar', |
184
|
|
|
'Content' => 'HTMLText', |
185
|
|
|
'HasBrokenFile' => 'Boolean' |
186
|
|
|
); |
187
|
|
|
} |
188
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.