Completed
Pull Request — master (#219)
by Markus
11:05
created

SymfonyMailerReporterTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Liip\MonitorBundle\Tests\Helper;
6
7
use Liip\MonitorBundle\Helper\SymfonyMailerReporter;
8
use PHPUnit\Framework\TestCase;
9
use Prophecy\Argument;
10
use Symfony\Component\Mailer\MailerInterface;
11
use Symfony\Component\Mime\Address;
12
use Symfony\Component\Mime\Email;
13
use ZendDiagnostics\Check\CheckInterface;
14
use ZendDiagnostics\Result\Collection;
15
use ZendDiagnostics\Result\Failure;
16
17
class SymfonyMailerReporterTest extends TestCase
18
{
19
    /**
20
     * @var \Prophecy\Prophecy\ObjectProphecy|MailerInterface
21
     */
22
    private $mailer;
23
24
    protected function setUp()
25
    {
26
        $this->mailer = $this->prophesize(MailerInterface::class);
27
    }
28
29
    /**
30
     * @dataProvider getTestData
31
     */
32
    public function testSendMail(array $recipients, string $sender, string $subject)
33
    {
34
        $reporter = new SymfonyMailerReporter($this->mailer->reveal(), $recipients, $sender, $subject);
0 ignored issues
show
Bug introduced by
The method reveal does only exist in Prophecy\Prophecy\ObjectProphecy, but not in Symfony\Component\Mailer\MailerInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
35
36
        $check = $this->prophesize(CheckInterface::class);
37
        $check->getLabel()->willReturn('Some Label');
38
39
        $checks = new Collection();
40
        $checks[$check->reveal()] = new Failure('Something goes wrong');
41
42
        $this->mailer->send(Argument::that(function(Email $message) use ($recipients, $sender, $subject): bool {
0 ignored issues
show
Documentation introduced by
\Prophecy\Argument::that...'); return true; }) is of type object<Prophecy\Argument\Token\CallbackToken>, but the function expects a object<Symfony\Component\Mime\RawMessage>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
The method send does only exist in Symfony\Component\Mailer\MailerInterface, but not in Prophecy\Prophecy\ObjectProphecy.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
43
            $this->assertEquals(Address::createArray($recipients), $message->getTo(), 'Check if Recipient is sent correctly.');
44
            $this->assertEquals([Address::create($sender)], $message->getFrom(), 'Check that the from header is set correctly.');
45
            $this->assertSame($subject, $message->getSubject(), 'Check that the subject has been set.');
46
47
            $this->assertSame('[Some Label] Something goes wrong', $message->getTextBody(), 'Check if the text body has been set.');
48
49
            return true;
50
        }))->shouldBeCalled();
51
52
        $reporter->onFinish($checks);
53
    }
54
55
    public static function getTestData(): iterable
56
    {
57
        return [
58
            [
59
                ['[email protected]'],
60
                '[email protected]',
61
                'Something went wrogin'
62
            ]
63
        ];
64
    }
65
}
66