Completed
Push — ignore/lazy-images-linting-pac... ( 3c044f...b5c515 )
by Jeremy
367:06 queued 352:42
created

WP_Test_Grunion_Contact_Form   F

Complexity

Total Complexity 77

Size/Duplication

Total Lines 1757
Duplicated Lines 24.42 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
dl 429
loc 1757
rs 1.04
c 0
b 0
f 0
wmc 77
lcom 2
cbo 4

61 Methods

Rating   Name   Duplication   Size   Complexity  
A setUpBeforeClass() 0 9 1
A set_globals() 0 5 1
A setUp() 0 32 1
A tearDown() 0 8 1
A add_field_values() 0 5 2
A test_process_submission_will_store_a_feedback_correctly_with_default_form() 0 16 1
A test_process_submission_will_store_extra_field_metadata() 0 39 1
A test_process_submission_will_store_subject_when_specified() 0 15 1
A test_process_submission_will_store_subject_with_token_replaced_from_name_and_text_field() 24 24 1
A test_process_submission_will_store_subject_with_token_replaced_from_radio_button_field() 23 23 1
A test_process_submission_will_store_subject_with_token_replaced_from_dropdown_field() 23 23 1
A test_process_submission_will_store_fields_and_their_values_to_post_content() 0 30 1
A test_process_submission_will_store_fields_and_their_values_to_email_meta() 0 37 1
A test_process_submission_sends_correct_single_email() 25 25 1
A pre_test_process_submission_sends_correct_single_email() 0 15 1
A test_process_submission_sends_correct_multiple_email() 26 26 1
A pre_test_process_submission_sends_correct_multiple_email() 0 3 1
A test_process_submission_fails_if_spam_marked_with_WP_Error() 0 9 1
A pre_test_process_submission_fails_if_spam_marked_with_WP_Error() 0 3 1
A test_process_submission_wont_send_spam_if_marked_as_spam_with_true() 9 9 1
A pre_test_process_submission_wont_send_spam_if_marked_as_spam_with_true() 0 3 1
A test_process_submission_labels_message_as_spam_in_subject_if_marked_as_spam_with_true_and_sending_spam() 11 11 1
A pre_test_process_submission_labels_message_as_spam_in_subject_if_marked_as_spam_with_true_and_sending_spam() 0 3 1
A test_grunion_delete_old_spam_deletes_an_old_post_marked_as_spam() 12 12 1
A test_grunion_delete_old_spam_does_not_delete_a_new_post_marked_as_spam() 11 11 1
A test_token_left_intact_when_no_matching_field() 9 9 1
A test_replaced_with_empty_string_when_no_value_in_field() 9 9 1
A test_token_can_replace_entire_subject_with_token_field_whose_name_has_whitespace() 9 9 1
A test_token_with_curly_brackets_can_be_replaced() 9 9 1
A test_parse_contact_field_keeps_string_unchanged_when_no_escaping_necesssary() 9 9 1
A test_make_sure_that_we_add_default_label_when_non_is_present() 7 7 1
A test_make_sure_that_we_remove_empty_options_from_form_field() 7 7 1
A test_array_values_with_commas_and_brackets() 6 6 1
A test_array_values_with_commas_and_brackets_from_gutenblock() 0 9 1
A test_make_sure_text_field_renders_as_expected() 13 13 1
A test_make_sure_email_field_renders_as_expected() 13 13 1
A test_make_sure_url_field_renders_as_expected() 13 13 1
A test_make_sure_telephone_field_renders_as_expected() 13 13 1
A test_make_sure_date_field_renders_as_expected() 13 13 1
A test_make_sure_textarea_field_renders_as_expected() 13 13 1
A test_make_sure_checkbox_field_renders_as_expected() 13 13 1
A test_make_sure_checkbox_multiple_field_renders_as_expected() 0 14 1
A test_make_sure_radio_field_renders_as_expected() 14 14 1
A test_make_sure_select_field_renders_as_expected() 14 14 1
A render_field() 0 5 1
A getCommonDiv() 0 5 1
A getFirstElement() 0 4 1
A assertCommonValidHtml() 0 16 2
B assertValidField() 13 56 4
A assertValidCheckboxField() 0 19 2
B assertValidFieldMultiField() 5 72 7
A test_parse_contact_field_escapes_things_inside_a_value_and_attribute_and_the_content() 12 12 1
B test_get_export_data_for_posts_fully_valid_data() 0 104 1
B test_get_export_data_for_posts_invalid_single_entry_meta() 0 95 1
B test_get_export_data_for_posts_invalid_all_entries_meta() 0 81 1
B test_get_export_data_for_posts_single_invalid_entry_for_parse_fields() 0 102 1
A test_get_export_data_for_posts_all_entries_for_parse_fields_invalid() 0 36 1
A test_map_parsed_field_contents_of_post_to_field_names() 0 25 1
A test_personal_data_exporter() 19 44 3
A test_personal_data_eraser() 16 33 2
B test_personal_data_eraser_pagination() 16 66 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like WP_Test_Grunion_Contact_Form often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WP_Test_Grunion_Contact_Form, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Unit Tests for Grunion_Contact_Form.
4
 *
5
 * @package Jetpack
6
 */
7
8
require_jetpack_file( 'modules/contact-form/grunion-contact-form.php' );
9
10
/**
11
 * Test class for Grunion_Contact_Form
12
 *
13
 * @covers Grunion_Contact_Form
14
 */
15
class WP_Test_Grunion_Contact_Form extends WP_UnitTestCase {
16
17
	/**
18
	 * Sets up the test environment before the class tests begin.
19
	 */
20
	public static function setUpBeforeClass() {
21
		parent::setUpBeforeClass();
22
		define( 'DOING_AJAX', true ); // Defined so that 'exit' is not called in process_submission.
23
24
		// Remove any relevant filters that might exist before running the tests.
25
		remove_all_filters( 'grunion_still_email_spam' );
26
		remove_all_filters( 'jetpack_contact_form_is_spam' );
27
		remove_all_filters( 'wp_mail' );
28
	}
29
30
	/**
31
	 * Inserts globals needed to process contact form submits
32
	 */
33
	private function set_globals() {
34
		$_SERVER['REMOTE_ADDR']     = '127.0.0.1';
35
		$_SERVER['HTTP_USER_AGENT'] = 'unit-test';
36
		$_SERVER['HTTP_REFERER']    = 'test';
37
	}
38
39
	/**
40
	 * Sets up the test environment before each unit test.
41
	 */
42
	public function setUp() {
43
		parent::setUp();
44
45
		$this->set_globals();
46
47
		$author_id = $this->factory->user->create(
48
			array(
49
				'user_email' => '[email protected]',
50
			)
51
		);
52
53
		$post_id = $this->factory->post->create(
54
			array(
55
				'post_status' => 'draft',
56
				'post_author' => (string) $author_id,
57
			)
58
		);
59
60
		global $post;
61
		$post = get_post( $post_id );
62
63
		// Place post_id to contact form id to make the form processable.
64
		$_POST['contact-form-id'] = $post_id;
65
66
		// Make the global post (used by contact forms) accessbile to tests.
67
		$this->post = $post;
68
69
		// Initialize plugin.
70
		$this->plugin = Grunion_Contact_Form_Plugin::init();
71
		// Call to add tokenization hook.
72
		$this->plugin->process_form_submission();
73
	}
74
75
	/**
76
	 * Tears down the test environment after each unit test.
77
	 */
78
	public function tearDown() {
79
		parent::tearDown();
80
81
		// Remove filters after running tests.
82
		remove_all_filters( 'wp_mail' );
83
		remove_all_filters( 'grunion_still_email_spam' );
84
		remove_all_filters( 'jetpack_contact_form_is_spam' );
85
	}
86
87
	/**
88
	 * Adds the field values to the global $_POST value.
89
	 *
90
	 * @param array $values Array of field key value pairs.
91
	 */
92
	private function add_field_values( $values ) {
93
		foreach ( $values as $key => $val ) {
94
			$_POST[ 'g' . $this->post->ID . '-' . $key ] = $val;
95
		}
96
	}
97
98
	/**
99
	 * Tests that the submission as a whole will produce something in the
100
	 * database when required information is provided.
101
	 *
102
	 * @author tonykova
103
	 */
104
	public function test_process_submission_will_store_a_feedback_correctly_with_default_form() {
105
		$form   = new Grunion_Contact_Form( array() );
106
		$result = $form->process_submission();
107
108
		// Processing should be successful and produce the success message.
109
		$this->assertTrue( is_string( $result ) );
110
111
		$feedback = get_posts( array( 'post_type' => 'feedback' ) );
112
		$this->assertSame( 1, count( $feedback ), 'There should be one feedback after process_submission' );
113
114
		// Default metadata should be saved.
115
		$submission = $feedback[0];
116
		$email      = get_post_meta( $submission->ID, '_feedback_email', true );
117
		$this->assertEquals( '"john" <[email protected]>', $email['to'][0] );
118
		$this->assertContains( 'IP Address: 127.0.0.1', $email['message'] );
119
	}
120
121
	/**
122
	 * Tests that the submission as a whole will produce something in the
123
	 * database when some labels are provided.
124
	 *
125
	 * @author tonykova
126
	 */
127
	public function test_process_submission_will_store_extra_field_metadata() {
128
		// Fill field values.
129
		$this->add_field_values(
130
			array(
131
				'name'     => 'John Doe',
132
				'dropdown' => 'First option',
133
				'radio'    => 'Second option',
134
				'text'     => 'Texty text',
135
			)
136
		);
137
138
		// Initialize a form with name, dropdown and radiobutton (first, second
139
		// and third option), text field.
140
		$form   = new Grunion_Contact_Form( array(), "[contact-field label='Name' type='name' required='1'/][contact-field label='Dropdown' type='select' options='First option,Second option,Third option'/][contact-field label='Radio' type='radio' options='First option,Second option,Third option'/][contact-field label='Text' type='text'/]" );
141
		$result = $form->process_submission();
142
143
		// Processing should be successful and produce the success message.
144
		$this->assertTrue( is_string( $result ) );
145
146
		$feedback = get_posts( array( 'post_type' => 'feedback' ) );
147
		$this->assertSame( 1, count( $feedback ), 'There should be one feedback after process_submission' );
148
149
		// Default metadata should be saved.
150
		$submission   = $feedback[0];
151
		$extra_fields = get_post_meta( $submission->ID, '_feedback_extra_fields', true );
152
153
		$this->assertSame( 3, count( $extra_fields ), 'There should be exactly three extra fields when one of the fields is name, and the others are an extra dropdown, radio button field and text field' );
154
155
		/*
156
		 * Metadata starts counting from 5, because post content has:
157
		 *   1_Name
158
		 *   2_Dropdown
159
		 *   3_Radio
160
		 *   4_Text
161
		 */
162
		$this->assertEquals( $extra_fields['5_Dropdown'], 'First option', 'When the first option of a dropdown field with label Dropdown is selected, there should be metadata with that key and value' );
163
		$this->assertEquals( $extra_fields['6_Radio'], 'Second option', 'When the first option of a radio button field with label Radio is selected, there should be metadata with that key and value' );
164
		$this->assertEquals( $extra_fields['7_Text'], 'Texty text', 'When the text field with label Text is filled with the text \'Texty text\', there should be metadata with that key and value' );
165
	}
166
167
	/**
168
	 * Tests that the submission will store the subject when specified.
169
	 *
170
	 * @author tonykova
171
	 */
172
	public function test_process_submission_will_store_subject_when_specified() {
173
		$form   = new Grunion_Contact_Form( array( 'subject' => 'I\'m sorry, but the party\'s over' ) ); // Default form.
174
		$result = $form->process_submission();
175
176
		// Processing should be successful and produce the success message.
177
		$this->assertTrue( is_string( $result ) );
178
179
		$feedback = get_posts( array( 'post_type' => 'feedback' ) );
180
		$this->assertSame( 1, count( $feedback ), 'There should be one feedback after process_submission' );
181
182
		// Default metadata should be saved.
183
		$submission = $feedback[0];
184
185
		$this->assertContains( 'SUBJECT: I\'m sorry, but the party\'s over', $submission->post_content, 'The stored subject didn\'t match the given' );
186
	}
187
188
	/**
189
	 * Tests that the submission will store the subject with tokens replace using the name and text fields.
190
	 *
191
	 * @author tonykova
192
	 */
193 View Code Duplication
	public function test_process_submission_will_store_subject_with_token_replaced_from_name_and_text_field() {
194
		// Fill field values.
195
		$this->add_field_values(
196
			array(
197
				'name'  => 'John Doe',
198
				'state' => 'Kansas',
199
			)
200
		);
201
202
		$form = new Grunion_Contact_Form( array( 'subject' => 'Hello {name} from {state}!' ), "[contact-field label='Name' type='name' required='1'/][contact-field label='State' type='text'/]" );
203
204
		$result = $form->process_submission();
205
206
		// Processing should be successful and produce the success message.
207
		$this->assertTrue( is_string( $result ) );
208
209
		$feedback = get_posts( array( 'post_type' => 'feedback' ) );
210
		$this->assertSame( 1, count( $feedback ), 'There should be one feedback after process_submission' );
211
212
		// Default metadata should be saved.
213
		$submission = $feedback[0];
214
215
		$this->assertContains( 'SUBJECT: Hello John Doe from Kansas!', $submission->post_content, 'The stored subject didn\'t match the given' );
216
	}
217
218
	/**
219
	 * Tests that the submission will store the subject with a token replaced using the radio button field.
220
	 *
221
	 * @author tonykova
222
	 */
223 View Code Duplication
	public function test_process_submission_will_store_subject_with_token_replaced_from_radio_button_field() {
224
		// Fill field values.
225
		$this->add_field_values(
226
			array(
227
				'name'  => 'John Doe',
228
				'state' => 'Kansas',
229
			)
230
		);
231
232
		$form   = new Grunion_Contact_Form( array( 'subject' => 'Hello {name} from {state}!' ), "[contact-field label='Name' type='name' required='1'/][contact-field label='State' type='radio' options='Kansas,California'/]" );
233
		$result = $form->process_submission();
234
235
		// Processing should be successful and produce the success message.
236
		$this->assertTrue( is_string( $result ) );
237
238
		$feedback = get_posts( array( 'post_type' => 'feedback' ) );
239
		$this->assertSame( 1, count( $feedback ), 'There should be one feedback after process_submission' );
240
241
		// Default metadata should be saved.
242
		$submission = $feedback[0];
243
244
		$this->assertContains( 'SUBJECT: Hello John Doe from Kansas!', $submission->post_content, 'The stored subject didn\'t match the given' );
245
	}
246
247
	/**
248
	 * Tests that the submission will store the subject with a token replaced using the dropdown field.
249
	 *
250
	 * @author tonykova
251
	 */
252 View Code Duplication
	public function test_process_submission_will_store_subject_with_token_replaced_from_dropdown_field() {
253
		// Fill field values.
254
		$this->add_field_values(
255
			array(
256
				'name'  => 'John Doe',
257
				'state' => 'Kansas',
258
			)
259
		);
260
261
		$form   = new Grunion_Contact_Form( array( 'subject' => 'Hello {name} from {state}!' ), "[contact-field label='Name' type='name' required='1'/][contact-field label='State' type='select' options='Kansas,California'/]" );
262
		$result = $form->process_submission();
263
264
		// Processing should be successful and produce the success message.
265
		$this->assertTrue( is_string( $result ) );
266
267
		$feedback = get_posts( array( 'post_type' => 'feedback' ) );
268
		$this->assertSame( 1, count( $feedback ), 'There should be one feedback after process_submission' );
269
270
		// Default metadata should be saved.
271
		$submission = $feedback[0];
272
273
		$this->assertContains( 'SUBJECT: Hello John Doe from Kansas!', $submission->post_content, 'The stored subject didn\'t match the given' );
274
	}
275
276
	/**
277
	 * Tests the form submission will store the fields and their values in the post content.
278
	 *
279
	 * @author tonykova
280
	 */
281
	public function test_process_submission_will_store_fields_and_their_values_to_post_content() {
282
		// Fill field values.
283
		$this->add_field_values(
284
			array(
285
				'name'     => 'John Doe',
286
				'dropdown' => 'First option',
287
				'radio'    => 'Second option',
288
				'text'     => 'Texty text',
289
			)
290
		);
291
292
		// Initialize a form with name, dropdown and radiobutton (first, second
293
		// and third option), text field.
294
		$form   = new Grunion_Contact_Form( array(), "[contact-field label='Name' type='name' required='1'/][contact-field label='Dropdown' type='select' options='First option,Second option,Third option'/][contact-field label='Radio' type='radio' options='First option,Second option,Third option'/][contact-field label='Text' type='text'/]" );
295
		$result = $form->process_submission();
296
297
		// Processing should be successful and produce the success message.
298
		$this->assertTrue( is_string( $result ) );
299
300
		$feedback = get_posts( array( 'post_type' => 'feedback' ) );
301
		$this->assertSame( 1, count( $feedback ), 'There should be one feedback after process_submission' );
302
303
		// Default metadata should be saved.
304
		$submission = $feedback[0];
305
306
		$this->assertContains( '[1_Name] =&gt; John Doe', $submission->post_content, 'Post content did not contain the name label and/or value' );
307
		$this->assertContains( '[2_Dropdown] =&gt; First option', $submission->post_content, 'Post content did not contain the dropdown label and/or value' );
308
		$this->assertContains( '[3_Radio] =&gt; Second option', $submission->post_content, 'Post content did not contain the radio button label and/or value' );
309
		$this->assertContains( '[4_Text] =&gt; Texty text', $submission->post_content, 'Post content did not contain the text field label and/or value' );
310
	}
311
312
	/**
313
	 * Tests that the form submission will store the fields and their value in the email meta.
314
	 *
315
	 * @author tonykova
316
	 */
317
	public function test_process_submission_will_store_fields_and_their_values_to_email_meta() {
318
		// Fill field values.
319
		$this->add_field_values(
320
			array(
321
				'name'     => 'John Doe',
322
				'dropdown' => 'First option',
323
				'radio'    => 'Second option',
324
				'text'     => 'Texty text',
325
			)
326
		);
327
328
		// Initialize a form with name, dropdown and radiobutton (first, second
329
		// and third option), text field.
330
		$form   = new Grunion_Contact_Form( array(), "[contact-field label='Name' type='name' required='1'/][contact-field label='Dropdown' type='select' options='First option,Second option,Third option'/][contact-field label='Radio' type='radio' options='First option,Second option,Third option'/][contact-field label='Text' type='text'/]" );
331
		$result = $form->process_submission();
332
333
		// Processing should be successful and produce the success message.
334
		$this->assertTrue( is_string( $result ) );
335
336
		$feedback = get_posts( array( 'post_type' => 'feedback' ) );
337
		$this->assertSame( 1, count( $feedback ), 'There should be one feedback after process_submission' );
338
339
		// Default metadata should be saved.
340
		$submission = $feedback[0];
341
		$email      = get_post_meta( $submission->ID, '_feedback_email', true );
342
343
		$expected  = '<b>Name:</b> John Doe<br /><br />';
344
		$expected .= '<b>Dropdown:</b> First option<br /><br />';
345
		$expected .= '<b>Radio:</b> Second option<br /><br />';
346
		$expected .= '<b>Text:</b> Texty text<br /><br />';
347
348
		$email_body = explode( PHP_EOL . PHP_EOL, $email['message'] );
349
350
		$email_body = $email_body[1];
351
352
		$this->assertStringStartsWith( $expected, $email_body );
353
	}
354
355
	/**
356
	 * Tests that the form subussion sends the correct single email.
357
	 *
358
	 * @author tonykova
359
	 */
360 View Code Duplication
	public function test_process_submission_sends_correct_single_email() {
361
		// Fill field values.
362
		$this->add_field_values(
363
			array(
364
				'name'     => 'John Doe',
365
				'dropdown' => 'First option',
366
				'radio'    => 'Second option',
367
				'text'     => 'Texty text',
368
			)
369
		);
370
371
		add_filter( 'wp_mail', array( $this, 'pre_test_process_submission_sends_correct_single_email' ) );
372
373
		// Initialize a form with name, dropdown and radiobutton (first, second
374
		// and third option), text field.
375
		$form   = new Grunion_Contact_Form(
376
			array(
377
				'to'      => '"john" <[email protected]>',
378
				'subject' => 'Hello there!',
379
			),
380
			"[contact-field label='Name' type='name' required='1'/][contact-field label='Dropdown' type='select' options='First option,Second option,Third option'/][contact-field label='Radio' type='radio' options='First option,Second option,Third option'/][contact-field label='Text' type='text'/]"
381
		);
382
		$result = $form->process_submission();
383
		$this->assertNotNull( $result );
384
	}
385
386
	/**
387
	 * This method is hooked to the wp-mail filter.
388
	 *
389
	 * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
390
	 *                    subject, message, headers, and attachments values.
391
	 */
392
	public function pre_test_process_submission_sends_correct_single_email( $args ) {
393
		$this->assertContains( '"john" <[email protected]>', $args['to'] );
394
		$this->assertEquals( 'Hello there!', $args['subject'] );
395
396
		$expected  = '<b>Name:</b> John Doe<br /><br />';
397
		$expected .= '<b>Dropdown:</b> First option<br /><br />';
398
		$expected .= '<b>Radio:</b> Second option<br /><br />';
399
		$expected .= '<b>Text:</b> Texty text<br /><br />';
400
401
		// Divides email by the first empty line.
402
		$email_body = explode( PHP_EOL . PHP_EOL, $args['message'] );
403
		$email_body = $email_body[1];
404
405
		$this->assertStringStartsWith( $expected, $email_body );
406
	}
407
408
	/**
409
	 * Tests that the form subussion sends the correct multiple emails.
410
	 *
411
	 * @author tonykova
412
	 */
413 View Code Duplication
	public function test_process_submission_sends_correct_multiple_email() {
414
		// Fill field values.
415
		$this->add_field_values(
416
			array(
417
				'name'     => 'John Doe',
418
				'dropdown' => 'First option',
419
				'radio'    => 'Second option',
420
				'text'     => 'Texty text',
421
			)
422
		);
423
424
		add_filter( 'wp_mail', array( $this, 'pre_test_process_submission_sends_correct_multiple_email' ) );
425
426
		// Initialize a form with name, dropdown and radiobutton (first, second
427
		// and third option), text field.
428
		$form = new Grunion_Contact_Form(
429
			array(
430
				'to'      => '[email protected], [email protected]',
431
				'subject' => 'Hello there!',
432
			),
433
			"[contact-field label='Name' type='name' required='1'/][contact-field label='Dropdown' type='select' options='First option,Second option,Third option'/][contact-field label='Radio' type='radio' options='First option,Second option,Third option'/][contact-field label='Text' type='text'/]"
434
		);
435
436
		$result = $form->process_submission();
437
		$this->assertNotNull( $result );
438
	}
439
440
	/**
441
	 * This method is hooked to the wp-mail filter.
442
	 *
443
	 * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
444
	 *                    subject, message, headers, and attachments values.
445
	 */
446
	public function pre_test_process_submission_sends_correct_multiple_email( $args ) {
447
		$this->assertEquals( array( '"john" <[email protected]>', '"jane" <[email protected]>' ), $args['to'] );
448
	}
449
450
	/**
451
	 * Tests that the form submission fails when spam is marked with a WP_Error object.
452
	 *
453
	 * @author tonykova
454
	 */
455
	public function test_process_submission_fails_if_spam_marked_with_WP_Error() {
456
		add_filter( 'jetpack_contact_form_is_spam', array( $this, 'pre_test_process_submission_fails_if_spam_marked_with_WP_Error' ), 11 ); // Run after akismet filter.
457
458
		$form   = new Grunion_Contact_Form( array() );
459
		$result = $form->process_submission();
460
461
		$this->assertInstanceOf( 'WP_Error', $result, 'When $is_spam contains a WP_Error, the result of process_submission should be a WP_Error' );
462
		$this->assertEquals( 'Message is spam', $result->get_error_message() );
463
	}
464
465
	/**
466
	 * This method is hooked to the jetpack_contact_form_is_spam filter.
467
	 */
468
	public function pre_test_process_submission_fails_if_spam_marked_with_WP_Error() {
469
		return new WP_Error( 'spam', 'Message is spam' );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'spam'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
470
	}
471
472
	/**
473
	 * Tests that the form submission won't send if the submission is marked as spam.
474
	 *
475
	 * @author tonykova
476
	 */
477 View Code Duplication
	public function test_process_submission_wont_send_spam_if_marked_as_spam_with_true() {
478
		add_filter( 'jetpack_contact_form_is_spam', '__return_true', 11 ); // Run after akismet filter.
479
480
		add_filter( 'wp_mail', array( $this, 'pre_test_process_submission_wont_send_spam_if_marked_as_spam_with_true' ) );
481
482
		$form   = new Grunion_Contact_Form( array( 'to' => '[email protected]' ) );
483
		$result = $form->process_submission();
484
		$this->assertNotNull( $result );
485
	}
486
487
	/**
488
	 * This method is hooked to the wp-mail filter, and the test will fail if this method is called.
489
	 */
490
	public function pre_test_process_submission_wont_send_spam_if_marked_as_spam_with_true() {
491
		$this->assertTrue( false ); // Fail if trying to send.
492
	}
493
494
	/**
495
	 * Tests that the email subject is labeled with Spam when the submission is spam and the filter to send spam is set to true.
496
	 *
497
	 * @author tonykova
498
	 */
499 View Code Duplication
	public function test_process_submission_labels_message_as_spam_in_subject_if_marked_as_spam_with_true_and_sending_spam() {
500
		add_filter( 'jetpack_contact_form_is_spam', '__return_true', 11 ); // Run after akismet filter.
501
502
		add_filter( 'grunion_still_email_spam', '__return_true' );
503
504
		add_filter( 'wp_mail', array( $this, 'pre_test_process_submission_labels_message_as_spam_in_subject_if_marked_as_spam_with_true_and_sending_spam' ) );
505
506
		$form   = new Grunion_Contact_Form( array( 'to' => '[email protected]' ) );
507
		$result = $form->process_submission();
508
		$this->assertNotNull( $result );
509
	}
510
511
	/**
512
	 * This method is hooked to the wp-mail filter.
513
	 *
514
	 * @param array $args A compacted array of wp_mail() arguments, including the "to" email,
515
	 *                    subject, message, headers, and attachments values.
516
	 */
517
	public function pre_test_process_submission_labels_message_as_spam_in_subject_if_marked_as_spam_with_true_and_sending_spam( $args ) {
518
		$this->assertContains( '***SPAM***', $args['subject'] );
519
	}
520
521
	/**
522
	 * Tests that 'grunion_delete_old_spam()' deletes an old post that is marked as spam.
523
	 *
524
	 * @author tonykova
525
	 * @covers ::grunion_delete_old_spam
526
	 */
527 View Code Duplication
	public function test_grunion_delete_old_spam_deletes_an_old_post_marked_as_spam() {
528
		$post_id = $this->factory->post->create(
529
			array(
530
				'post_type'     => 'feedback',
531
				'post_status'   => 'spam',
532
				'post_date_gmt' => '1987-01-01 12:00:00',
533
			)
534
		);
535
536
		grunion_delete_old_spam();
537
		$this->assertNull( get_post( $post_id ), 'An old spam feedback should be deleted' );
538
	}
539
540
	/**
541
	 * Tests that 'grunion_delete_old_spam' does not delete a new post that is marked as spam.
542
	 *
543
	 * @author tonykova
544
	 * @covers ::grunion_delete_old_spam
545
	 */
546 View Code Duplication
	public function test_grunion_delete_old_spam_does_not_delete_a_new_post_marked_as_spam() {
547
		$post_id = $this->factory->post->create(
548
			array(
549
				'post_type'   => 'feedback',
550
				'post_status' => 'spam',
551
			)
552
		);
553
554
		grunion_delete_old_spam();
555
		$this->assertEquals( $post_id, get_post( $post_id )->ID, 'A new spam feedback should be left intact when deleting old spam' );
556
	}
557
558
	/**
559
	 * Tests that token is left intact when there is not matching field.
560
	 *
561
	 * @author tonykova
562
	 * @covers Grunion_Contact_Form_Plugin
563
	 */
564 View Code Duplication
	public function test_token_left_intact_when_no_matching_field() {
565
		$plugin       = Grunion_Contact_Form_Plugin::init();
566
		$subject      = 'Hello {name}!';
567
		$field_values = array(
568
			'City' => 'Chicago',
569
		);
570
571
		$this->assertEquals( 'Hello {name}!', $plugin->replace_tokens_with_input( $subject, $field_values ) );
572
	}
573
574
	/**
575
	 * Tests that token is replaced with an empty string when there is not value in field.
576
	 *
577
	 * @author tonykova
578
	 * @covers Grunion_Contact_Form_Plugin
579
	 */
580 View Code Duplication
	public function test_replaced_with_empty_string_when_no_value_in_field() {
581
		$plugin       = Grunion_Contact_Form_Plugin::init();
582
		$subject      = 'Hello {name}!';
583
		$field_values = array(
584
			'Name' => null,
585
		);
586
587
		$this->assertEquals( 'Hello !', $plugin->replace_tokens_with_input( $subject, $field_values ) );
588
	}
589
590
	/**
591
	 * Tests that token in curly brackets is replaced with the value when the name has whitespace.
592
	 *
593
	 * @author tonykova
594
	 * @covers Grunion_Contact_Form_Plugin
595
	 */
596 View Code Duplication
	public function test_token_can_replace_entire_subject_with_token_field_whose_name_has_whitespace() {
597
		$plugin       = Grunion_Contact_Form_Plugin::init();
598
		$subject      = '{subject token}';
599
		$field_values = array(
600
			'Subject Token' => 'Chicago',
601
		);
602
603
		$this->assertEquals( 'Chicago', $plugin->replace_tokens_with_input( $subject, $field_values ) );
604
	}
605
606
	/**
607
	 * Tests that token with curly brackets is replaced with value.
608
	 *
609
	 * @author tonykova
610
	 * @covers Grunion_Contact_Form_Plugin
611
	 */
612 View Code Duplication
	public function test_token_with_curly_brackets_can_be_replaced() {
613
		$plugin       = Grunion_Contact_Form_Plugin::init();
614
		$subject      = '{subject {token}}';
615
		$field_values = array(
616
			'Subject {Token}' => 'Chicago',
617
		);
618
619
		$this->assertEquals( 'Chicago', $plugin->replace_tokens_with_input( $subject, $field_values ) );
620
	}
621
622
	/**
623
	 * Tests that the field attributes remain the same when no escaping is necessary.
624
	 *
625
	 * @author tonykova
626
	 */
627 View Code Duplication
	public function test_parse_contact_field_keeps_string_unchanged_when_no_escaping_necesssary() {
628
		add_shortcode( 'contact-field', array( 'Grunion_Contact_Form', 'parse_contact_field' ) );
629
630
		// @phpcs:ignore Squiz.Strings.DoubleQuoteUsage.NotRequired
631
		$shortcode = "[contact-field label=\"Name\" type=\"name\" required=\"1\"/][contact-field label=\"Email\" type=\"email\" required=\"1\"/][contact-field label=\"asdasd\" type=\"text\"/][contact-field id=\"1\" required derp herp asd lkj]adsasd[/contact-field]";
632
		$html      = do_shortcode( $shortcode );
633
634
		$this->assertEquals( $shortcode, $html );
635
	}
636
637
	/**
638
	 * Tests that the default label is added when no label is present.
639
	 */
640 View Code Duplication
	public function test_make_sure_that_we_add_default_label_when_non_is_present() {
641
		add_shortcode( 'contact-field', array( 'Grunion_Contact_Form', 'parse_contact_field' ) );
642
		$shortcode = "[contact-field type='name' required='1' /]";
643
		$html      = do_shortcode( $shortcode );
644
		// @phpcs:ignore Squiz.Strings.DoubleQuoteUsage.NotRequired
645
		$this->assertEquals( "[contact-field type=\"name\" required=\"1\" label=\"Name\"/]", $html );
646
	}
647
648
	/**
649
	 * Tests the empty options are removed from form fields.
650
	 */
651 View Code Duplication
	public function test_make_sure_that_we_remove_empty_options_from_form_field() {
652
		add_shortcode( 'contact-field', array( 'Grunion_Contact_Form', 'parse_contact_field' ) );
653
		$shortcode = "[contact-field type='select' required='1' options='fun,,run' label='fun times' values='go,,have some fun'/]";
654
		$html      = do_shortcode( $shortcode );
655
		// @phpcs:ignore Squiz.Strings.DoubleQuoteUsage.NotRequired
656
		$this->assertEquals( "[contact-field type=\"select\" required=\"1\" options=\"fun,run\" label=\"fun times\" values=\"go,have some fun\"/]", $html );
657
	}
658
659
	/**
660
	 * Tests shortcode with commas and brackets.
661
	 *
662
	 * @covers Grunion_Contact_Form_Field
663
	 */
664 View Code Duplication
	public function test_array_values_with_commas_and_brackets() {
665
		add_shortcode( 'contact-field', array( 'Grunion_Contact_Form', 'parse_contact_field' ) );
666
		$shortcode = "[contact-field type='radio' options='\"foo\",bar&#044; baz,&#091;b&#092;rackets&#093;' label='fun &#093;&#091; times'/]";
667
		$html      = do_shortcode( $shortcode );
668
		$this->assertEquals( '[contact-field type="radio" options="&quot;foo&quot;,bar&#044; baz,&#091;b&#092;rackets&#093;" label="fun &#093;&#091; times"/]', $html );
669
	}
670
671
	/**
672
	 * Tests Gutenblock input with commas and brackets.
673
	 *
674
	 * @covers Grunion_Contact_Form_Field
675
	 */
676
	public function test_array_values_with_commas_and_brackets_from_gutenblock() {
677
		$attr = array(
678
			'type'    => 'radio',
679
			'options' => array( '"foo"', 'bar, baz', '[b\\rackets]' ),
680
			'label'   => 'fun ][ times',
681
		);
682
		$html = Grunion_Contact_Form_Plugin::gutenblock_render_field_radio( $attr, '' );
683
		$this->assertEquals( '[contact-field type="radio" options="&quot;foo&quot;,bar&#044; baz,&#091;b&#092;rackets&#093;" label="fun &#093;&#091; times"/]', $html );
684
	}
685
686
	/**
687
	 * Test for text field_renders
688
	 *
689
	 * @covers Grunion_Contact_Form_Field
690
	 */
691 View Code Duplication
	public function test_make_sure_text_field_renders_as_expected() {
692
		$attributes = array(
693
			'label'       => 'fun',
694
			'type'        => 'text',
695
			'class'       => 'lalala',
696
			'default'     => 'foo',
697
			'placeholder' => 'PLACEHOLDTHIS!',
698
			'id'          => 'funID',
699
		);
700
701
		$expected_attributes = array_merge( $attributes, array( 'input_type' => 'text' ) );
702
		$this->assertValidField( $this->render_field( $attributes ), $expected_attributes );
703
	}
704
705
	/**
706
	 * Test for email field_renders
707
	 *
708
	 * @covers Grunion_Contact_Form_Field
709
	 */
710 View Code Duplication
	public function test_make_sure_email_field_renders_as_expected() {
711
		$attributes = array(
712
			'label'       => 'fun',
713
			'type'        => 'email',
714
			'class'       => 'lalala',
715
			'default'     => 'foo',
716
			'placeholder' => 'PLACEHOLDTHIS!',
717
			'id'          => 'funID',
718
		);
719
720
		$expected_attributes = array_merge( $attributes, array( 'input_type' => 'email' ) );
721
		$this->assertValidField( $this->render_field( $attributes ), $expected_attributes );
722
	}
723
724
	/**
725
	 * Test for url field_renders
726
	 *
727
	 * @covers Grunion_Contact_Form_Field
728
	 */
729 View Code Duplication
	public function test_make_sure_url_field_renders_as_expected() {
730
		$attributes = array(
731
			'label'       => 'fun',
732
			'type'        => 'url',
733
			'class'       => 'lalala',
734
			'default'     => 'foo',
735
			'placeholder' => 'PLACEHOLDTHIS!',
736
			'id'          => 'funID',
737
		);
738
739
		$expected_attributes = array_merge( $attributes, array( 'input_type' => 'url' ) );
740
		$this->assertValidField( $this->render_field( $attributes ), $expected_attributes );
741
	}
742
743
	/**
744
	 * Test for telephone field_renders
745
	 *
746
	 * @covers Grunion_Contact_Form_Field
747
	 */
748 View Code Duplication
	public function test_make_sure_telephone_field_renders_as_expected() {
749
		$attributes = array(
750
			'label'       => 'fun',
751
			'type'        => 'telephone',
752
			'class'       => 'lalala',
753
			'default'     => 'foo',
754
			'placeholder' => 'PLACEHOLDTHIS!',
755
			'id'          => 'funID',
756
		);
757
758
		$expected_attributes = array_merge( $attributes, array( 'input_type' => 'tel' ) );
759
		$this->assertValidField( $this->render_field( $attributes ), $expected_attributes );
760
	}
761
762
	/**
763
	 * Test for date field_renders
764
	 *
765
	 * @covers Grunion_Contact_Form_Field
766
	 */
767 View Code Duplication
	public function test_make_sure_date_field_renders_as_expected() {
768
		$attributes = array(
769
			'label'       => 'fun',
770
			'type'        => 'date',
771
			'class'       => 'lalala',
772
			'default'     => 'foo',
773
			'placeholder' => 'PLACEHOLDTHIS!',
774
			'id'          => 'funID',
775
		);
776
777
		$expected_attributes = array_merge( $attributes, array( 'input_type' => 'text' ) );
778
		$this->assertValidField( $this->render_field( $attributes ), $expected_attributes );
779
	}
780
781
	/**
782
	 * Test for textarea field_renders
783
	 *
784
	 * @covers Grunion_Contact_Form_Field
785
	 */
786 View Code Duplication
	public function test_make_sure_textarea_field_renders_as_expected() {
787
		$attributes = array(
788
			'label'       => 'fun',
789
			'type'        => 'textarea',
790
			'class'       => 'lalala',
791
			'default'     => 'foo',
792
			'placeholder' => 'PLACEHOLDTHIS!',
793
			'id'          => 'funID',
794
		);
795
796
		$expected_attributes = array_merge( $attributes, array( 'input_type' => 'textarea' ) );
797
		$this->assertValidField( $this->render_field( $attributes ), $expected_attributes );
798
	}
799
800
	/**
801
	 * Test for checkbox field_renders
802
	 *
803
	 * @covers Grunion_Contact_Form_Field
804
	 */
805 View Code Duplication
	public function test_make_sure_checkbox_field_renders_as_expected() {
806
		$attributes = array(
807
			'label'       => 'fun',
808
			'type'        => 'checkbox',
809
			'class'       => 'lalala',
810
			'default'     => 'foo',
811
			'placeholder' => 'PLACEHOLDTHIS!',
812
			'id'          => 'funID',
813
		);
814
815
		$expected_attributes = array_merge( $attributes, array( 'input_type' => 'checkbox' ) );
816
		$this->assertValidCheckboxField( $this->render_field( $attributes ), $expected_attributes );
817
	}
818
819
	/**
820
	 * Multiple fields
821
	 *
822
	 * @covers Grunion_Contact_Form_Field
823
	 */
824
	public function test_make_sure_checkbox_multiple_field_renders_as_expected() {
825
		$attributes = array(
826
			'label'   => 'fun',
827
			'type'    => 'checkbox-multiple',
828
			'class'   => 'lalala',
829
			'default' => 'option 1',
830
			'id'      => 'funID',
831
			'options' => array( 'option 1', 'option 2' ),
832
			'values'  => array( 'option 1', 'option 2' ),
833
		);
834
835
		$expected_attributes = array_merge( $attributes, array( 'input_type' => 'checkbox' ) );
836
		$this->assertValidFieldMultiField( $this->render_field( $attributes ), $expected_attributes );
837
	}
838
839
	/**
840
	 * Test for radio field_renders
841
	 *
842
	 * @covers Grunion_Contact_Form_Field
843
	 */
844 View Code Duplication
	public function test_make_sure_radio_field_renders_as_expected() {
845
		$attributes = array(
846
			'label'   => 'fun',
847
			'type'    => 'radio',
848
			'class'   => 'lalala',
849
			'default' => 'option 1',
850
			'id'      => 'funID',
851
			'options' => array( 'option 1', 'option 2', 'option 3, or 4', 'back\\slash' ),
852
			'values'  => array( 'option 1', 'option 2', 'option [34]', '\\' ),
853
		);
854
855
		$expected_attributes = array_merge( $attributes, array( 'input_type' => 'radio' ) );
856
		$this->assertValidFieldMultiField( $this->render_field( $attributes ), $expected_attributes );
857
	}
858
859
	/**
860
	 * Test for select field_renders
861
	 *
862
	 * @covers Grunion_Contact_Form_Field
863
	 */
864 View Code Duplication
	public function test_make_sure_select_field_renders_as_expected() {
865
		$attributes = array(
866
			'label'   => 'fun',
867
			'type'    => 'select',
868
			'class'   => 'lalala',
869
			'default' => 'option 1',
870
			'id'      => 'funID',
871
			'options' => array( 'option 1', 'option 2', 'option 3, or 4', 'back\\slash' ),
872
			'values'  => array( 'option 1', 'option 2', 'option [34]', '\\' ),
873
		);
874
875
		$expected_attributes = array_merge( $attributes, array( 'input_type' => 'select' ) );
876
		$this->assertValidFieldMultiField( $this->render_field( $attributes ), $expected_attributes );
877
	}
878
879
	/**
880
	 * Renders a Grunion_Contact_Form_Field.
881
	 *
882
	 * @param array $attributes An associative array of shortcode attributes.
883
	 *
884
	 * @return string The field html string.
885
	 */
886
	public function render_field( $attributes ) {
887
		$form  = new Grunion_Contact_Form( array() );
888
		$field = new Grunion_Contact_Form_Field( $attributes, '', $form );
889
		return $field->render();
890
	}
891
892
	/**
893
	 * Gets the first div in the input html.
894
	 *
895
	 * @param string $html The html string.
896
	 *
897
	 * @return DOMElement The first div element.
898
	 */
899
	public function getCommonDiv( $html ) {
900
		$doc = new DOMDocument();
901
		$doc->loadHTML( $html );
902
		return $this->getFirstElement( $doc, 'div' );
903
	}
904
905
	/**
906
	 * Gets the first element in the given DOMDocument object.
907
	 *
908
	 * @param DOMDocument $dom The DOMDocument object.
909
	 * @param string      $tag The tag name.
910
	 * @param int         $index The index.
911
	 *
912
	 * @return DOMElement The first element with the given tag.
913
	 */
914
	public function getFirstElement( $dom, $tag, $index = 0 ) {
915
		$elements = $dom->getElementsByTagName( $tag );
916
		return $elements->item( $index );
917
	}
918
919
	/**
920
	 * Tests whether the class attribute in the wrapper div matches the field's class attribute value.
921
	 *
922
	 * @param DOMElement $wrapper_div The wrapper div.
923
	 * @param array      $attributes An associative array containing the field's attributes.
924
	 */
925
	public function assertCommonValidHtml( $wrapper_div, $attributes ) {
926
		if ( 'date' === $attributes['type'] ) {
927
			$attributes['class'] = 'jp-contact-form-date';
928
		}
929
		$this->assertEquals(
930
			$wrapper_div->getAttribute( 'class' ),
931
			"grunion-field-wrap grunion-field-{$attributes['type']}-wrap {$attributes['class']}-wrap",
932
			'div class attribute doesn\'t match'
933
		);
934
935
		// Get label.
936
		$label = $this->getFirstElement( $wrapper_div, 'label' );
937
938
		// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
939
		$this->assertEquals( trim( $label->nodeValue ), $attributes['label'], 'Label is not what we expect it to be...' );
940
	}
941
942
	/**
943
	 * Tests whether a field is valid.
944
	 *
945
	 * @param string $html The html string.
946
	 * @param array  $attributes An associative array containing the field's attributes.
947
	 */
948
	public function assertValidField( $html, $attributes ) {
949
950
		$wrapper_div = $this->getCommonDiv( $html );
951
		$this->assertCommonValidHtml( $wrapper_div, $attributes );
952
953
		// Get label.
954
		$label = $this->getFirstElement( $wrapper_div, 'label' );
955
956
		// Input.
957
		$input = (
958
			'textarea' === $attributes['type']
959
			? $this->getFirstElement( $wrapper_div, 'textarea' )
960
			: $this->getFirstElement( $wrapper_div, 'input' )
961
		);
962
963
		// Label matches for matches input ID.
964
		$this->assertEquals(
965
			$label->getAttribute( 'for' ),
966
			$input->getAttribute( 'id' ),
967
			'label for does not equal input ID!'
968
		);
969
970
		$this->assertEquals( $input->getAttribute( 'placeholder' ), $attributes['placeholder'], 'Placeholder doesn\'t match' );
971
		if ( 'textarea' === $attributes['type'] ) {
972
			// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
973
			$this->assertEquals( $input->nodeValue, $attributes['default'], 'value and default doesn\'t match' );
974
			$this->assertEquals(
975
				$label->getAttribute( 'for' ),
976
				'contact-form-comment-' . $input->getAttribute( 'name' ),
977
				'label for doesn\'t match the input name'
978
			);
979
		} else {
980
			$this->assertEquals( $input->getAttribute( 'type' ), $attributes['input_type'], 'Type doesn\'t match' );
981
			$this->assertEquals( $input->getAttribute( 'value' ), $attributes['default'], 'value and default doesn\'t match' );
982
			// Label matches for matches input name.
983
			$this->assertEquals(
984
				$label->getAttribute( 'for' ),
985
				$input->getAttribute( 'name' ),
986
				'label for doesn\'t match the input name'
987
			);
988
		}
989
990 View Code Duplication
		if ( 'date' === $attributes['type'] ) {
991
			$this->assertEquals(
992
				$input->getAttribute( 'class' ),
993
				"{$attributes['type']} jp-contact-form-date",
994
				'input class attribute doesn\'t match'
995
			);
996
		} else {
997
			$this->assertEquals(
998
				$input->getAttribute( 'class' ),
999
				"{$attributes['type']} {$attributes['class']}",
1000
				'input class attribute doesn\'t match'
1001
			);
1002
		}
1003
	}
1004
1005
	/**
1006
	 * Tests whether a checkbox field is valid.
1007
	 *
1008
	 * @param string $html The html string.
1009
	 * @param array  $attributes An associative array containing the field's attributes.
1010
	 */
1011
	public function assertValidCheckboxField( $html, $attributes ) {
1012
1013
		$wrapper_div = $this->getCommonDiv( $html );
1014
		$this->assertCommonValidHtml( $wrapper_div, $attributes );
1015
1016
		$label = $this->getFirstElement( $wrapper_div, 'label' );
1017
		$input = $this->getFirstElement( $label, 'input' );
1018
1019
		$this->assertEquals( $label->getAttribute( 'class' ), 'grunion-field-label ' . $attributes['type'], 'label class doesn\'t match' );
1020
1021
		$this->assertEquals( $input->getAttribute( 'name' ), $attributes['id'], 'Input name doesn\'t match' );
1022
		$this->assertEquals( $input->getAttribute( 'value' ), 'Yes', 'Input value doesn\'t match' );
1023
		$this->assertEquals( $input->getAttribute( 'type' ), $attributes['type'], 'Input type doesn\'t match' );
1024
		if ( $attributes['default'] ) {
1025
			$this->assertEquals( $input->getAttribute( 'checked' ), 'checked', 'Input checked doesn\'t match' );
1026
		}
1027
1028
		$this->assertEquals( $input->getAttribute( 'class' ), $attributes['type'] . ' ' . $attributes['class'], 'Input class doesn\'t match' );
1029
	}
1030
1031
	/**
1032
	 * Tests whether a multifield contact form field is valid.
1033
	 *
1034
	 * @param string $html The html string.
1035
	 * @param array  $attributes An associative array containing the field's attributes.
1036
	 */
1037
	public function assertValidFieldMultiField( $html, $attributes ) {
1038
1039
		$wrapper_div = $this->getCommonDiv( $html );
1040
		$this->assertCommonValidHtml( $wrapper_div, $attributes );
1041
1042
		// Get label.
1043
		$label = $this->getFirstElement( $wrapper_div, 'label' );
1044
1045
		// Inputs.
1046
		if ( 'select' === $attributes['type'] ) {
1047
			$this->assertEquals( $label->getAttribute( 'class' ), 'grunion-field-label select', 'label class doesn\'t match' );
1048
1049
			$select = $this->getFirstElement( $wrapper_div, 'select' );
1050
			$this->assertEquals(
1051
				$label->getAttribute( 'for' ),
1052
				$select->getAttribute( 'id' ),
1053
				'label for does not equal input ID!'
1054
			);
1055
1056
			$this->assertEquals(
1057
				$label->getAttribute( 'for' ),
1058
				$select->getAttribute( 'name' ),
1059
				'label for does not equal input name!'
1060
			);
1061
1062
			$this->assertEquals( $select->getAttribute( 'class' ), 'select ' . $attributes['class'], ' select class does not match expected' );
1063
1064
			// Options.
1065
			$options = $select->getElementsByTagName( 'option' );
1066
			$n       = $options->length;
1067
			$this->assertEquals( $n, count( $attributes['options'] ), 'Number of inputs doesn\'t match number of options' );
1068
			$this->assertEquals( $n, count( $attributes['values'] ), 'Number of inputs doesn\'t match number of values' );
1069
			for ( $i = 0; $i < $n; $i++ ) {
1070
				$option = $options->item( $i );
1071
				$this->assertEquals( $option->getAttribute( 'value' ), $attributes['values'][ $i ], 'Input value doesn\'t match' );
1072
				if ( 0 === $i ) {
1073
					$this->assertEquals( $option->getAttribute( 'selected' ), 'selected', 'Input is not selected' );
1074
				} else {
1075
					$this->assertNotEquals( $option->getAttribute( 'selected' ), 'selected', 'Input is selected' );
1076
				}
1077
				//phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
1078
				$this->assertEquals( $option->nodeValue, $attributes['options'][ $i ], 'Input does not match the option' );
1079
			}
1080
		} else {
1081
			$this->assertEquals( $label->getAttribute( 'class' ), 'grunion-field-label', 'label class doesn\'t match' );
1082
			// Radio and Checkboxes.
1083
			$labels = $wrapper_div->getElementsByTagName( 'label' );
1084
			$n      = $labels->length - 1;
1085
			$this->assertEquals( $n, count( $attributes['options'] ), 'Number of inputs doesn\'t match number of options' );
1086
			$this->assertEquals( $n, count( $attributes['values'] ), 'Number of inputs doesn\'t match number of values' );
1087
			for ( $i = 0; $i < $n; $i++ ) {
1088
				$item_label = $labels->item( $i + 1 );
1089
				//phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
1090
				$this->assertEquals( $item_label->nodeValue, ' ' . $attributes['options'][ $i ] ); // extra space added for a padding.
1091
1092
				$input = $this->getFirstElement( $item_label, 'input' );
1093
				$this->assertEquals( $input->getAttribute( 'type' ), $attributes['input_type'], 'Type doesn\'t match' );
1094 View Code Duplication
				if ( 'radio' === $attributes['input_type'] ) {
1095
					$this->assertEquals( $input->getAttribute( 'name' ), $attributes['id'], 'Input name doesn\'t match' );
1096
				} else {
1097
					$this->assertEquals( $input->getAttribute( 'name' ), $attributes['id'] . '[]', 'Input name doesn\'t match' );
1098
				}
1099
				$this->assertEquals( $input->getAttribute( 'value' ), $attributes['values'][ $i ], 'Input value doesn\'t match' );
1100
				$this->assertEquals( $input->getAttribute( 'class' ), $attributes['type'] . ' ' . $attributes['class'], 'Input class doesn\'t match' );
1101
				if ( 0 === $i ) {
1102
					$this->assertEquals( $input->getAttribute( 'checked' ), 'checked', 'Input checked doesn\'t match' );
1103
				} else {
1104
					$this->assertNotEquals( $input->getAttribute( 'checked' ), 'checked', 'Input checked doesn\'t match' );
1105
				}
1106
			}
1107
		}
1108
	}
1109
1110
	/**
1111
	 * Tests that the form attributes and values are properly escaped.
1112
	 *
1113
	 * @author tonykova
1114
	 */
1115 View Code Duplication
	public function test_parse_contact_field_escapes_things_inside_a_value_and_attribute_and_the_content() {
1116
		add_shortcode( 'contact-field', array( 'Grunion_Contact_Form', 'parse_contact_field' ) );
1117
1118
		$shortcode = "[contact-field label='Name' type='name' required='1'/][contact-field label='Email' type=''email'' req'uired='1'/][contact-field label='asdasd' type='text'/][contact-field id='1' required 'derp' herp asd lkj]adsasd[/contact-field]";
1119
		$html      = do_shortcode( $shortcode );
1120
1121
		/*
1122
		 * The expected string has some quotes escaped, since we want to make
1123
		 * sure we don't output anything harmful
1124
		 */
1125
		$this->assertEquals( '[contact-field label="Name" type="name" required="1"/][contact-field label="Email" type=&#039;&#039;email&#039;&#039; req&#039;uired=&#039;1&#039;/][contact-field label="asdasd" type="text"/][contact-field id="1" required derp herp asd lkj]adsasd[/contact-field]', $html );
1126
	}
1127
1128
	/**
1129
	 * Test get_export_data_for_posts with fully vaid data input.
1130
	 *
1131
	 * @covers Grunion_Contact_Form_Plugin
1132
	 * @group csvexport
1133
	 */
1134
	public function test_get_export_data_for_posts_fully_valid_data() {
1135
		/**
1136
		 * Grunion_Contact_Form_Plugin mock object.
1137
		 *
1138
		 * @var Grunion_Contact_Form_Plugin $mock
1139
		 */
1140
		$mock = $this->getMockBuilder( 'Grunion_Contact_Form_Plugin' )
1141
			->setMethods(
1142
				array(
1143
					'get_post_meta_for_csv_export',
1144
					'get_parsed_field_contents_of_post',
1145
					'get_post_content_for_csv_export',
1146
					'map_parsed_field_contents_of_post_to_field_names',
1147
				)
1148
			)
1149
			->disableOriginalConstructor()
1150
			->getMock();
1151
1152
		$get_post_meta_for_csv_export_map = array(
1153
			array(
1154
				15,
1155
				array(
1156
					'key1' => 'value1',
1157
					'key2' => 'value2',
1158
					'key3' => 'value3',
1159
					'key4' => 'value4',
1160
1161
				),
1162
			),
1163
			array(
1164
				16,
1165
				array(
1166
					'key3' => 'value3',
1167
					'key4' => 'value4',
1168
					'key5' => 'value5',
1169
					'key6' => 'value6',
1170
				),
1171
			),
1172
		);
1173
1174
		$get_parsed_field_contents_of_post_map = array(
1175
			array( 15, array( '_feedback_subject' => 'subj1' ) ),
1176
			array( 16, array( '_feedback_subject' => 'subj2' ) ),
1177
		);
1178
1179
		$get_post_content_for_csv_export_map = array(
1180
			array( 15, 'This is my test 15' ),
1181
			array( 16, 'This is my test 16' ),
1182
		);
1183
1184
		$mapped_fields_contents_map = array(
1185
			array(
1186
				array(
1187
					'_feedback_subject'      => 'subj1',
1188
					'_feedback_main_comment' => 'This is my test 15',
1189
				),
1190
				array(
1191
					'Contact Form' => 'subj1',
1192
					'4_Comment'    => 'This is my test 15',
1193
				),
1194
			),
1195
			array(
1196
				array(
1197
					'_feedback_subject'      => 'subj2',
1198
					'_feedback_main_comment' => 'This is my test 16',
1199
				),
1200
				array(
1201
					'Contact Form' => 'subj2',
1202
					'4_Comment'    => 'This is my test 16',
1203
				),
1204
			),
1205
		);
1206
1207
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1208
			->method( 'get_post_meta_for_csv_export' )
1209
			->will( $this->returnValueMap( $get_post_meta_for_csv_export_map ) );
1210
1211
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1212
			->method( 'get_parsed_field_contents_of_post' )
1213
			->will( $this->returnValueMap( $get_parsed_field_contents_of_post_map ) );
1214
1215
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1216
			->method( 'get_post_content_for_csv_export' )
1217
			->will( $this->returnValueMap( $get_post_content_for_csv_export_map ) );
1218
1219
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1220
			->method( 'map_parsed_field_contents_of_post_to_field_names' )
1221
			->will( $this->returnValueMap( $mapped_fields_contents_map ) );
1222
1223
		$result = $mock->get_export_data_for_posts( array( 15, 16 ) );
1224
1225
		$expected_result = array(
1226
			'Contact Form' => array( 'subj1', 'subj2' ),
1227
			'key1'         => array( 'value1', '' ),
1228
			'key2'         => array( 'value2', '' ),
1229
			'key3'         => array( 'value3', 'value3' ),
1230
			'key4'         => array( 'value4', 'value4' ),
1231
			'key5'         => array( '', 'value5' ),
1232
			'key6'         => array( '', 'value6' ),
1233
			'4_Comment'    => array( 'This is my test 15', 'This is my test 16' ),
1234
		);
1235
1236
		$this->assertEquals( $expected_result, $result );
1237
	}
1238
1239
	/**
1240
	 * Test get_export_data_for_posts with single invalid entry for post meta
1241
	 *
1242
	 * @covers Grunion_Contact_Form_Plugin
1243
	 * @group csvexport
1244
	 */
1245
	public function test_get_export_data_for_posts_invalid_single_entry_meta() {
1246
		/**
1247
		 * Grunion_Contact_Form_Plugin mock object.
1248
		 *
1249
		 * @var Grunion_Contact_Form_Plugin $mock
1250
		 * */
1251
		$mock = $this->getMockBuilder( 'Grunion_Contact_Form_Plugin' )
1252
			->setMethods(
1253
				array(
1254
					'get_post_meta_for_csv_export',
1255
					'get_parsed_field_contents_of_post',
1256
					'get_post_content_for_csv_export',
1257
					'map_parsed_field_contents_of_post_to_field_names',
1258
				)
1259
			)
1260
			->disableOriginalConstructor()
1261
			->getMock();
1262
1263
		$get_post_meta_for_csv_export_map = array(
1264
			array( 15, null ),
1265
			array(
1266
				16,
1267
				array(
1268
					'key3' => 'value3',
1269
					'key4' => 'value4',
1270
					'key5' => 'value5',
1271
					'key6' => 'value6',
1272
				),
1273
			),
1274
		);
1275
1276
		$get_parsed_field_contents_of_post_map = array(
1277
			array( 15, array( '_feedback_subject' => 'subj1' ) ),
1278
			array( 16, array( '_feedback_subject' => 'subj2' ) ),
1279
		);
1280
1281
		$get_post_content_for_csv_export_map = array(
1282
			array( 15, 'This is my test 15' ),
1283
			array( 16, 'This is my test 16' ),
1284
		);
1285
1286
		$mapped_fields_contents_map = array(
1287
			array(
1288
				array(
1289
					'_feedback_subject'      => 'subj1',
1290
					'_feedback_main_comment' => 'This is my test 15',
1291
				),
1292
				array(
1293
					'Contact Form' => 'subj1',
1294
					'4_Comment'    => 'This is my test 15',
1295
				),
1296
			),
1297
			array(
1298
				array(
1299
					'_feedback_subject'      => 'subj2',
1300
					'_feedback_main_comment' => 'This is my test 16',
1301
				),
1302
				array(
1303
					'Contact Form' => 'subj2',
1304
					'4_Comment'    => 'This is my test 16',
1305
				),
1306
			),
1307
		);
1308
1309
		// Even though there is no post meta for the first, we don't stop the cycle
1310
		// and each mock expects two calls.
1311
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1312
			->method( 'get_post_meta_for_csv_export' )
1313
			->will( $this->returnValueMap( $get_post_meta_for_csv_export_map ) );
1314
1315
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1316
			->method( 'get_parsed_field_contents_of_post' )
1317
			->will( $this->returnValueMap( $get_parsed_field_contents_of_post_map ) );
1318
1319
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1320
			->method( 'get_post_content_for_csv_export' )
1321
			->will( $this->returnValueMap( $get_post_content_for_csv_export_map ) );
1322
1323
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1324
			->method( 'map_parsed_field_contents_of_post_to_field_names' )
1325
			->will( $this->returnValueMap( $mapped_fields_contents_map ) );
1326
1327
		$result = $mock->get_export_data_for_posts( array( 15, 16 ) );
1328
1329
		$expected_result = array(
1330
			'Contact Form' => array( 'subj1', 'subj2' ),
1331
			'key3'         => array( '', 'value3' ),
1332
			'key4'         => array( '', 'value4' ),
1333
			'key5'         => array( '', 'value5' ),
1334
			'key6'         => array( '', 'value6' ),
1335
			'4_Comment'    => array( 'This is my test 15', 'This is my test 16' ),
1336
		);
1337
1338
		$this->assertEquals( $expected_result, $result );
1339
	}
1340
1341
	/**
1342
	 * Test get_export_data_for_posts with invalid all entries for post meta
1343
	 *
1344
	 * @covers Grunion_Contact_Form_Plugin
1345
	 * @group csvexport
1346
	 */
1347
	public function test_get_export_data_for_posts_invalid_all_entries_meta() {
1348
		/**
1349
		 * Grunion_Contact_Form_Plugin mock object.
1350
		 *
1351
		 * @var Grunion_Contact_Form_Plugin $mock
1352
		 */
1353
		$mock = $this->getMockBuilder( 'Grunion_Contact_Form_Plugin' )
1354
			->setMethods(
1355
				array(
1356
					'get_post_meta_for_csv_export',
1357
					'get_parsed_field_contents_of_post',
1358
					'get_post_content_for_csv_export',
1359
					'map_parsed_field_contents_of_post_to_field_names',
1360
				)
1361
			)
1362
			->disableOriginalConstructor()
1363
			->getMock();
1364
1365
		$get_post_meta_for_csv_export_map = array(
1366
			array( 15, null ),
1367
			array( 16, null ),
1368
		);
1369
1370
		$get_parsed_field_contents_of_post_map = array(
1371
			array( 15, array( '_feedback_subject' => 'subj1' ) ),
1372
			array( 16, array( '_feedback_subject' => 'subj2' ) ),
1373
		);
1374
1375
		$get_post_content_for_csv_export_map = array(
1376
			array( 15, 'This is my test 15' ),
1377
			array( 16, 'This is my test 16' ),
1378
		);
1379
1380
		$mapped_fields_contents_map = array(
1381
			array(
1382
				array(
1383
					'_feedback_subject'      => 'subj1',
1384
					'_feedback_main_comment' => 'This is my test 15',
1385
				),
1386
				array(
1387
					'Contact Form' => 'subj1',
1388
					'4_Comment'    => 'This is my test 15',
1389
				),
1390
			),
1391
			array(
1392
				array(
1393
					'_feedback_subject'      => 'subj2',
1394
					'_feedback_main_comment' => 'This is my test 16',
1395
				),
1396
				array(
1397
					'Contact Form' => 'subj2',
1398
					'4_Comment'    => 'This is my test 16',
1399
				),
1400
			),
1401
		);
1402
1403
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1404
			->method( 'get_post_meta_for_csv_export' )
1405
			->will( $this->returnValueMap( $get_post_meta_for_csv_export_map ) );
1406
1407
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1408
			->method( 'get_parsed_field_contents_of_post' )
1409
			->will( $this->returnValueMap( $get_parsed_field_contents_of_post_map ) );
1410
1411
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1412
			->method( 'get_post_content_for_csv_export' )
1413
			->will( $this->returnValueMap( $get_post_content_for_csv_export_map ) );
1414
1415
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1416
			->method( 'map_parsed_field_contents_of_post_to_field_names' )
1417
			->will( $this->returnValueMap( $mapped_fields_contents_map ) );
1418
1419
		$result = $mock->get_export_data_for_posts( array( 15, 16 ) );
1420
1421
		$expected_result = array(
1422
			'Contact Form' => array( 'subj1', 'subj2' ),
1423
			'4_Comment'    => array( 'This is my test 15', 'This is my test 16' ),
1424
		);
1425
1426
		$this->assertEquals( $expected_result, $result );
1427
	}
1428
1429
	/**
1430
	 * Test get_export_data_for_posts with single invalid entry for parsed fields.
1431
	 *
1432
	 * @covers Grunion_Contact_Form_Plugin
1433
	 * @group csvexport
1434
	 */
1435
	public function test_get_export_data_for_posts_single_invalid_entry_for_parse_fields() {
1436
		/**
1437
		 * Grunion_Contact_Form_Plugin mock object.
1438
		 *
1439
		 * @var Grunion_Contact_Form_Plugin $mock
1440
		 * */
1441
		$mock = $this->getMockBuilder( 'Grunion_Contact_Form_Plugin' )
1442
			->setMethods(
1443
				array(
1444
					'get_post_meta_for_csv_export',
1445
					'get_parsed_field_contents_of_post',
1446
					'get_post_content_for_csv_export',
1447
					'map_parsed_field_contents_of_post_to_field_names',
1448
				)
1449
			)
1450
			->disableOriginalConstructor()
1451
			->getMock();
1452
1453
		$get_post_meta_for_csv_export_map = array(
1454
			array(
1455
				15,
1456
				array(
1457
					'key1' => 'value1',
1458
					'key2' => 'value2',
1459
					'key3' => 'value3',
1460
					'key4' => 'value4',
1461
1462
				),
1463
			),
1464
			array(
1465
				16,
1466
				array(
1467
					'key3' => 'value3',
1468
					'key4' => 'value4',
1469
					'key5' => 'value5',
1470
					'key6' => 'value6',
1471
				),
1472
			),
1473
		);
1474
1475
		$get_parsed_field_contents_of_post_map = array(
1476
			array( 15, array() ),
1477
			array( 16, array( '_feedback_subject' => 'subj2' ) ),
1478
		);
1479
1480
		$get_post_content_for_csv_export_map = array(
1481
			array( 15, 'This is my test 15' ),
1482
			array( 16, 'This is my test 16' ),
1483
		);
1484
1485
		$mapped_fields_contents_map = array(
1486
			array(
1487
				array(
1488
					'_feedback_subject'      => 'subj1',
1489
					'_feedback_main_comment' => 'This is my test 15',
1490
				),
1491
				array(
1492
					'Contact Form' => 'subj1',
1493
					'4_Comment'    => 'This is my test 15',
1494
				),
1495
			),
1496
			array(
1497
				array(
1498
					'_feedback_subject'      => 'subj2',
1499
					'_feedback_main_comment' => 'This is my test 16',
1500
				),
1501
				array(
1502
					'Contact Form' => 'subj2',
1503
					'4_Comment'    => 'This is my test 16',
1504
				),
1505
			),
1506
		);
1507
1508
		$mock->expects( $this->exactly( 1 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1509
			->method( 'get_post_meta_for_csv_export' )
1510
			->will( $this->returnValueMap( $get_post_meta_for_csv_export_map ) );
1511
1512
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1513
			->method( 'get_parsed_field_contents_of_post' )
1514
			->will( $this->returnValueMap( $get_parsed_field_contents_of_post_map ) );
1515
1516
		$mock->expects( $this->exactly( 1 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1517
			->method( 'get_post_content_for_csv_export' )
1518
			->will( $this->returnValueMap( $get_post_content_for_csv_export_map ) );
1519
1520
		$mock->expects( $this->exactly( 1 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1521
			->method( 'map_parsed_field_contents_of_post_to_field_names' )
1522
			->will( $this->returnValueMap( $mapped_fields_contents_map ) );
1523
1524
		$result = $mock->get_export_data_for_posts( array( 15, 16 ) );
1525
1526
		$expected_result = array(
1527
			'Contact Form' => array( 'subj2' ),
1528
			'key3'         => array( 'value3' ),
1529
			'key4'         => array( 'value4' ),
1530
			'key5'         => array( 'value5' ),
1531
			'key6'         => array( 'value6' ),
1532
			'4_Comment'    => array( 'This is my test 16' ),
1533
		);
1534
1535
		$this->assertEquals( $expected_result, $result );
1536
	}
1537
1538
	/**
1539
	 * Test get_export_data_for_posts with all entries for parsed fields invalid.
1540
	 *
1541
	 * @covers Grunion_Contact_Form_Plugin
1542
	 * @group csvexport
1543
	 */
1544
	public function test_get_export_data_for_posts_all_entries_for_parse_fields_invalid() {
1545
		/**
1546
		 * Grunion_Contact_Form_Plugin mock object.
1547
		 *
1548
		 * @var Grunion_Contact_Form_Plugin $mock
1549
		 */
1550
		$mock = $this->getMockBuilder( 'Grunion_Contact_Form_Plugin' )
1551
			->setMethods(
1552
				array(
1553
					'get_post_meta_for_csv_export',
1554
					'get_parsed_field_contents_of_post',
1555
					'get_post_content_for_csv_export',
1556
					'map_parsed_field_contents_of_post_to_field_names',
1557
				)
1558
			)
1559
			->disableOriginalConstructor()
1560
			->getMock();
1561
1562
		$get_parsed_field_contents_of_post_map = array(
1563
			array( 15, array() ),
1564
			array( 16, array() ),
1565
		);
1566
1567
		$mock->expects( $this->never() )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1568
			->method( 'get_post_meta_for_csv_export' );
1569
1570
		$mock->expects( $this->exactly( 2 ) )
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Grunion_Contact_Form_Plugin>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1571
			->method( 'get_parsed_field_contents_of_post' )
1572
			->will( $this->returnValueMap( $get_parsed_field_contents_of_post_map ) );
1573
1574
		$result = $mock->get_export_data_for_posts( array( 15, 16 ) );
1575
1576
		$expected_result = array();
1577
1578
		$this->assertEquals( $expected_result, $result );
1579
	}
1580
1581
	/**
1582
	 * Test map_parsed_field_contents_of_post_to_field_names
1583
	 *
1584
	 * @covers Grunion_Contact_Form_Plugin
1585
	 * @group csvexport
1586
	 */
1587
	public function test_map_parsed_field_contents_of_post_to_field_names() {
1588
1589
		$input_data = array(
1590
			'test_field'             => 'moonstruck',
1591
			'_feedback_subject'      => 'This is my form',
1592
			'_feedback_author_email' => '',
1593
			'_feedback_author'       => 'John Smith',
1594
			'_feedback_author_url'   => 'http://example.com',
1595
			'_feedback_main_comment' => 'This is my comment!',
1596
			'another_field'          => 'thunderstruck',
1597
		);
1598
1599
		$plugin = Grunion_Contact_Form_Plugin::init();
1600
1601
		$result = $plugin->map_parsed_field_contents_of_post_to_field_names( $input_data );
1602
1603
		$expected_result = array(
1604
			'Contact Form' => 'This is my form',
1605
			'1_Name'       => 'John Smith',
1606
			'3_Website'    => 'http://example.com',
1607
			'4_Comment'    => 'This is my comment!',
1608
		);
1609
1610
		$this->assertEquals( $expected_result, $result );
1611
	}
1612
1613
	/**
1614
	 * Tests the functionality of 'Grunion_Contact_Form_Plugin::personal_data_exporter'.
1615
	 *
1616
	 * @author jaswrks
1617
	 */
1618
	public function test_personal_data_exporter() {
1619
		$this->add_field_values(
1620
			array(
1621
				'name'     => 'John Doe',
1622
				'email'    => '[email protected]',
1623
				'dropdown' => 'First option',
1624
				'radio'    => 'Second option',
1625
				'text'     => 'Texty text',
1626
			)
1627
		);
1628
1629 View Code Duplication
		for ( $i = 1; $i <= 2; $i++ ) {
1630
			$form = new Grunion_Contact_Form(
1631
				array(
1632
					'to'      => '"john" <[email protected]>',
1633
					'subject' => 'Hello world! [ ' . wp_rand() . ' ]',
1634
				),
1635
				'
1636
					[contact-field label="Name" type="name" required="1"/]
1637
					[contact-field label="Email" type="email" required="1"/]
1638
					[contact-field label="Dropdown" type="select" options="First option,Second option,Third option"/]
1639
					[contact-field label="Radio" type="radio" options="First option,Second option,Third option"/]
1640
					[contact-field label="Text" type="text"/]
1641
				'
1642
			);
1643
			$this->assertTrue(
1644
				is_string( $form->process_submission() ),
1645
				'form submission ' . $i
1646
			);
1647
		}
1648
1649
		$posts  = get_posts( array( 'post_type' => 'feedback' ) );
1650
		$export = $this->plugin->personal_data_exporter( '[email protected]' );
1651
1652
		$this->assertSame( 2, count( $posts ), 'posts count matches' );
1653
		$this->assertSame( 2, count( $export['data'] ), 'export[data] count matches' );
1654
1655
		foreach ( $export['data'] as $data ) {
1656
			$this->assertSame( 'feedback', $data['group_id'], 'group_id matches' );
1657
			$this->assertSame( 'Feedback', $data['group_label'], 'group_label matches' );
1658
			$this->assertSame( true, ! empty( $data['item_id'] ), 'has item_id key' );
1659
			$this->assertSame( 9, count( $data['data'] ), 'has total expected data keys' );
1660
		}
1661
	}
1662
1663
	/**
1664
	 * Tests the functionality of 'Grunion_Contact_Form_Plugin::personal_data_eraser'.
1665
	 *
1666
	 * @author jaswrks
1667
	 */
1668
	public function test_personal_data_eraser() {
1669
		$this->add_field_values(
1670
			array(
1671
				'name'  => 'John Doe',
1672
				'email' => '[email protected]',
1673
			)
1674
		);
1675
1676 View Code Duplication
		for ( $i = 1; $i <= 2; $i++ ) {
1677
			$form = new Grunion_Contact_Form(
1678
				array(
1679
					'to'      => '"john" <[email protected]>',
1680
					'subject' => 'Hello world! [ ' . wp_rand() . ' ]',
1681
				),
1682
				'
1683
					[contact-field label="Name" type="name" required="1"/]
1684
					[contact-field label="Email" type="email" required="1"/]
1685
				'
1686
			);
1687
			$this->assertTrue(
1688
				is_string( $form->process_submission() ),
1689
				'form submission ' . $i
1690
			);
1691
		}
1692
1693
		$posts = get_posts( array( 'post_type' => 'feedback' ) );
1694
		$this->assertSame( 2, count( $posts ), 'posts count matches before erasing' );
1695
1696
		$this->plugin->personal_data_eraser( '[email protected]' );
1697
1698
		$posts = get_posts( array( 'post_type' => 'feedback' ) );
1699
		$this->assertSame( 0, count( $posts ), 'posts count matches after erasing' );
1700
	}
1701
1702
	/**
1703
	 * Tests the functionality of 'Grunion_Contact_Form_Plugin::personal_data_eraser' with pagination.
1704
	 */
1705
	public function test_personal_data_eraser_pagination() {
1706
		$this->add_field_values(
1707
			array(
1708
				'name'  => 'Jane Doe',
1709
				'email' => '[email protected]',
1710
			)
1711
		);
1712
1713 View Code Duplication
		for ( $i = 1; $i <= 3; $i++ ) {
1714
			$form = new Grunion_Contact_Form(
1715
				array(
1716
					'to'      => '"jane" <[email protected]>',
1717
					'subject' => 'Hello world! [ ' . wp_rand() . ' ]',
1718
				),
1719
				'
1720
					[contact-field label="Name" type="name" required="1"/]
1721
					[contact-field label="Email" type="email" required="1"/]
1722
				'
1723
			);
1724
			$this->assertTrue(
1725
				is_string( $form->process_submission() ),
1726
				'form submission ' . $i
1727
			);
1728
		}
1729
1730
		$this->add_field_values(
1731
			array(
1732
				'name'  => 'Jane Doe Again',
1733
				'email' => '[email protected]',
1734
			)
1735
		);
1736
1737
		$form = new Grunion_Contact_Form(
1738
			array(
1739
				'to'      => '"jane" <[email protected]>',
1740
				'subject' => 'Hello world! [ ' . wp_rand() . ' ]',
1741
			),
1742
			'
1743
				[contact-field label="Name" type="name" required="1"/]
1744
				[contact-field label="Email" type="email" required="1"/]
1745
			'
1746
		);
1747
		$this->assertTrue(
1748
			is_string( $form->process_submission() ),
1749
			'form submission ' . $i
1750
		);
1751
1752
		$posts = get_posts( array( 'post_type' => 'feedback' ) );
1753
		$this->assertSame( 4, count( $posts ), 'posts count matches before erasing' );
1754
1755
		$this->plugin->_internal_personal_data_eraser( '[email protected]', 1, 1 );
1756
		$posts = get_posts( array( 'post_type' => 'feedback' ) );
1757
		$this->assertSame( 3, count( $posts ), 'posts count matches after page 1' );
1758
1759
		$this->plugin->_internal_personal_data_eraser( '[email protected]', 2, 1 );
1760
		$posts = get_posts( array( 'post_type' => 'feedback' ) );
1761
		$this->assertSame( 2, count( $posts ), 'posts count matches after page 2' );
1762
1763
		$this->plugin->_internal_personal_data_eraser( '[email protected]', 3, 1 );
1764
		$posts = get_posts( array( 'post_type' => 'feedback' ) );
1765
		$this->assertSame( 1, count( $posts ), 'posts count matches after page 3' );
1766
1767
		$this->plugin->_internal_personal_data_eraser( '[email protected]', 1, 1 );
1768
		$posts = get_posts( array( 'post_type' => 'feedback' ) );
1769
		$this->assertSame( 0, count( $posts ), 'posts count matches after deleting the other feedback responder' );
1770
	}
1771
} // end class
1772