diff --git a/tests/Plugin/Forminator/ForminatorTest.php b/tests/Plugin/Forminator/ForminatorTest.php
new file mode 100644
index 0000000..3fee1f4
--- /dev/null
+++ b/tests/Plugin/Forminator/ForminatorTest.php
@@ -0,0 +1,235 @@
+alias(function ($text) {
+ return $text;
+ });
+ Functions\when('get_option')->alias(function ($option_name) {
+ $mock_values = [
+ 'adcaptcha_placement_id' => 'mocked-placement-id',
+ ];
+ return $mock_values[$option_name] ?? null;
+ });
+ Functions\when('sanitize_text_field')->alias(function($input) {
+ $sanitized = strip_tags($input);
+ $sanitized = preg_replace('/[\r\n\t]/', ' ', $sanitized);
+ $sanitized = trim($sanitized);
+ return $sanitized;
+ });
+ Functions\when('__')->alias(function ($text, $domain = null) {
+ return $text;
+ });
+
+ $this->forms = new Forms();
+
+ $this->verifyMock = $this->createMock(Verify::class);
+ $reflection = new \ReflectionClass($this->forms);
+ $property = $reflection->getProperty('verify');
+ $property->setAccessible(true);
+ $property->setValue($this->forms, $this->verifyMock);
+ }
+
+ public function tearDown(): void {
+ global $mocked_filters;
+ $mocked_filters = [];
+ Mockery::close();
+ Monkey\tearDown();
+ parent::tearDown();
+ }
+
+ // Test method that verifies the existence of the 'setup' method and checks that specific WordPress hooks are properly registered with the expected callbacks and priorities.
+ public function testSetup() {
+ $this->assertTrue(method_exists($this->forms, 'setup'), 'Method setup does not exist');
+ global $mocked_actions, $mocked_filters;
+ $this->assertContains(
+ ['hook' => 'forminator_before_form_render', 'callback' => [$this->forms, 'before_form_render'], 'priority' => 10, 'accepted_args' => 5],
+ $mocked_actions
+ );
+ $this->assertContains(
+ ['hook' => 'forminator_before_form_render', 'callback' => [AdCaptcha::class, 'enqueue_scripts'], 'priority' => 9, 'accepted_args' => 1],
+ $mocked_actions
+ );
+ $this->assertContains(
+ ['hook' => 'forminator_before_form_render', 'callback' => [Verify::class, 'get_success_token'], 'priority' => 9, 'accepted_args' => 1],
+ $mocked_actions
+ );
+ $this->assertContains(
+ ['hook' => 'wp_enqueue_scripts', 'callback' => [$this->forms, 'reset_captcha_script'], 'priority' => 9, 'accepted_args' => 1],
+ $mocked_actions
+ );
+ $this->assertContains(
+ ['hook' => 'forminator_render_button_markup', 'callback' => [$this->forms, 'captcha_trigger_filter'], 'priority' => 10, 'accepted_args' => 2],
+ $mocked_filters
+ );
+ $this->assertContains(
+ ['hook' => 'forminator_cform_form_is_submittable', 'callback' => [$this->forms, 'verify'], 'priority' => 10, 'accepted_args' => 3],
+ $mocked_filters
+ );
+ }
+
+ // Tests if 'beforeFormRender' sets 'has_captcha' to true for 'adcaptcha' and false otherwise.
+ public function testBeforeFormRender() {
+ $reflection = new \ReflectionClass($this->forms);
+ $property = $reflection->getProperty('has_captcha');
+ $property->setAccessible(true);
+
+ $this->forms->before_form_render(1, 'contact_form', 123, [
+ ['type' => 'captcha', 'captcha_provider' => 'adcaptcha']
+ ], []);
+ $this->assertTrue($property->getValue($this->forms), "Expected has_captcha to be true");
+ $this->forms->before_form_render(1, 'contact_form', 123, [
+ ['type' => 'captcha', 'captcha_provider' => 'nocaptcha']
+ ], []);
+ $this->assertFalse($property->getValue($this->forms), "Expected has_captcha to be false");
+ }
+
+ // Tests if 'hasAdcaptchaField' correctly identifies the presence of an 'adcaptcha' field in various form field scenarios.
+ public function testHasAdcaptchaField() {
+ $this->assertTrue(method_exists($this->forms, 'has_adcaptcha_field'), 'Method has_adcaptcha_field does not exist');
+
+ $reflection = new \ReflectionClass($this->forms);
+ $method = $reflection->getMethod('has_adcaptcha_field');
+ $method->setAccessible(true);
+
+ $testCases = [
+ 'Valid adCaptcha field' => [
+ 'input' => [['type' => 'captcha', 'captcha_provider' => 'adcaptcha']],
+ 'expected' => true
+ ],
+ 'Different captcha provider' => [
+ 'input' => [['type' => 'captcha', 'captcha_provider' => 'nocaptcha']],
+ 'expected' => false
+ ],
+ 'Missing captcha provider' => [
+ 'input' => [['type' => 'captcha']],
+ 'expected' => false
+ ],
+ 'Missing type' => [
+ 'input' => [['captcha_provider' => 'adcaptcha']],
+ 'expected' => false
+ ],
+ 'Empty fields' => [
+ 'input' => [],
+ 'expected' => false
+ ],
+ 'Different field type' => [
+ 'input' => [['type' => 'text', 'captcha_provider' => 'adcaptcha']],
+ 'expected' => false
+ ],
+ 'Multiple fields with valid captcha' => [
+ 'input' => [
+ ['type' => 'text'],
+ ['type' => 'captcha', 'captcha_provider' => 'adcaptcha']
+ ],
+ 'expected' => true
+ ]
+ ];
+ foreach ($testCases as $description => $testCase) {
+ $result = $method->invoke($this->forms, $testCase['input']);
+ $this->assertSame($testCase['expected'], $result, "Failed: {$description}");
+ }
+ }
+
+ // Tests if 'captchaTriggerFilter' returns the original HTML when 'has_captcha' is true and prepends the captcha trigger when false.
+ public function testCaptchaTriggerFilter() {
+ $this->assertTrue(method_exists($this->forms, 'captcha_trigger_filter'), 'Method captcha_trigger_filter does not exist in Forms class');
+
+ $reflection = new \ReflectionClass($this->forms);
+ $property = $reflection->getProperty('has_captcha');
+ $property->setAccessible(true);
+ $property->setValue($this->forms, true);
+
+ $mockHtml = '';
+ $result = $this->forms->captcha_trigger_filter($mockHtml, 'button');
+ $this->assertEquals($mockHtml, $result, 'Expected HTML when has_captcha is true');
+
+ $property->setValue($this->forms, false);
+ $expectedHtml = AdCaptcha::ob_captcha_trigger() . $mockHtml;
+ $result = $this->forms->captcha_trigger_filter($mockHtml, 'button');
+ $this->assertEquals($expectedHtml, $result, 'Expected HTML when has_captcha is false');
+ }
+
+ // Tests if 'reset_captcha_script' correctly registers a JavaScript snippet via 'wp_footer' to reset AdCaptcha after form submission.
+ public function testResetCaptchaScript() {
+ $this->assertTrue(method_exists($this->forms, 'reset_captcha_script'), 'Method reset_captcha_script does not exist in Forms class');
+ Functions\expect('add_action')
+ ->once()
+ ->with('wp_footer', \Mockery::type('callable'))
+ ->andReturnUsing(function($hook, $callback) {
+ ob_start();
+ $callback();
+ $output = ob_get_clean();
+ $expectedScript = '';
+
+ $this->assertStringContainsString($expectedScript, $output);
+ });
+ $this->forms->reset_captcha_script();
+ }
+
+ public function testVerifyFailsWhenTokenIsMissing() {
+ Functions\when('wp_unslash')->justReturn('');
+ $_POST['adcaptcha_successToken'] = '';
+ $result = $this->forms->verify(true, 123, []);
+
+ $this->assertFalse($result['can_submit']);
+ $this->assertEquals('Please complete the AdCaptcha verification.', $result['error']);
+ }
+
+ public function testVerifyFailsWhenTokenVerificationFails() {
+ Functions\when('wp_unslash')->justReturn('invalid_token');
+ $this->verifyMock->method('verify_token')->willReturn(false);
+ $result = $this->forms->verify(true, 123, []);
+
+ $this->assertFalse($result['can_submit']);
+ $this->assertEquals('AdCaptcha verification failed. Please try again.', $result['error']);
+ }
+
+ public function testVerifySucceedsWhenTokenIsValid() {
+ Functions\when('wp_unslash')->justReturn('valid_token');
+ $this->verifyMock->method('verify_token')->willReturn(true);
+ $result = $this->forms->verify(true, 123, []);
+ $this->assertTrue(method_exists($this->forms, 'verify'), 'Method verify does not exist in Forms class');
+ $this->assertTrue($result);
+ }
+ }
+
\ No newline at end of file