Passed
Pull Request — master (#99)
by
unknown
13:18
created

ActionTest   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 65
dl 0
loc 146
rs 10
c 4
b 0
f 0
wmc 9
1
<?php
2
/**
3
 * PHP Billing Library
4
 *
5
 * @link      https://github.com/hiqdev/php-billing
6
 * @package   php-billing
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017-2020, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\php\billing\tests\unit\action;
12
13
use DateTimeImmutable;
14
use hiqdev\php\billing\action\Action;
15
use hiqdev\php\billing\charge\Charge;
16
use hiqdev\php\billing\charge\ChargeInterface;
17
use hiqdev\php\billing\charge\Generalizer;
18
use hiqdev\php\billing\customer\Customer;
19
use hiqdev\php\billing\customer\CustomerInterface;
20
use hiqdev\php\billing\Exception\CannotReassignException;
21
use hiqdev\php\billing\order\Calculator;
22
use hiqdev\php\billing\plan\Plan;
23
use hiqdev\php\billing\price\SinglePrice;
24
use hiqdev\php\billing\sale\Sale;
25
use hiqdev\php\billing\target\Target;
26
use hiqdev\php\billing\tests\support\plan\SimplePlanRepository;
27
use hiqdev\php\billing\tests\support\sale\SimpleSaleRepository;
28
use hiqdev\php\billing\tools\CachedDateTimeProvider;
29
use hiqdev\php\billing\type\Type;
30
use hiqdev\php\units\Quantity;
31
use hiqdev\php\units\QuantityInterface;
32
use Money\Money;
33
34
/**
35
 * @author Andrii Vasyliev <[email protected]>
36
 */
37
class ActionTest extends \PHPUnit\Framework\TestCase
38
{
39
    /**
40
     * @var SinglePrice
41
     */
42
    protected $price;
43
44
    /**
45
     * @var Action
46
     */
47
    protected $action;
48
49
    /**
50
     * @var Money
51
     */
52
    protected $money;
53
    /**
54
     * @var Type
55
     */
56
    protected $type;
57
    /**
58
     * @var Target
59
     */
60
    protected $target;
61
    /**
62
     * @var QuantityInterface
63
     */
64
    protected $prepaid;
65
    /**
66
     * @var Customer|CustomerInterface
67
     */
68
    protected $customer;
69
    /**
70
     * @var DateTimeImmutable
71
     */
72
    protected $time;
73
    /**
74
     * @var Generalizer
75
     */
76
    protected $generalizer;
77
    /**
78
     * @var Calculator
79
     */
80
    protected $calculator;
81
82
    protected $testId = 12321;
83
84
    protected function setUp(): void
85
    {
86
        $this->type     = Type::anyId('server_traf');
87
        $this->target   = new Target(2, 'server');
88
        $this->prepaid  = Quantity::gigabyte(1);
89
        $this->money    = Money::USD(10000);
90
        $this->price    = new SinglePrice(5, $this->type, $this->target, null, $this->prepaid, $this->money);
91
        $this->customer = new Customer(2, 'client');
92
        $this->time     = new DateTimeImmutable('now');
93
        $this->generalizer = new Generalizer();
94
        $saleRepository = new SimpleSaleRepository();
95
        $planRepository = new SimplePlanRepository();
96
        $timeProvider = new CachedDateTimeProvider($this->time);
97
        $this->calculator = new Calculator($this->generalizer, $saleRepository, $planRepository, $timeProvider);
98
    }
99
100
    protected function createAction(QuantityInterface $quantity)
101
    {
102
        return new Action(null, $this->type, $this->target, $quantity, $this->customer, $this->time);
103
    }
104
105
    protected function tearDown(): void
106
    {
107
    }
108
109
    public function testCalculateCharge()
110
    {
111
        $action = $this->createAction($this->prepaid->multiply(2));
112
        $charge = $this->calculator->calculateCharge($this->price, $action);
113
        $this->assertInstanceOf(Charge::class, $charge);
114
        $this->assertSame($action, $charge->getAction());
115
        //$this->assertSame($this->target, $charge->getTarget());
116
        $this->assertSame($this->type, $charge->getType());
117
        $this->assertEquals($this->prepaid, $charge->getUsage());
118
        $this->assertEquals($this->money->multiply((string)$this->prepaid->getQuantity()), $charge->getSum());
119
    }
120
121
    public function testCalculateChargeNull()
122
    {
123
        $action = $this->createAction($this->prepaid);
124
        $charge = $this->calculator->calculateCharge($this->price, $action);
125
        $this->assertZeroCharge($charge);
126
    }
127
128
    public function assertZeroCharge(ChargeInterface $charge): void
129
    {
130
        $this->assertSame('0', $charge->getSum()->getAmount());
131
    }
132
133
    public function testChargesForNextMonthSalesAreNotCalculated()
134
    {
135
        $action = $this->createAction($this->prepaid->multiply(2));
136
137
        $plan = new Plan(null, '', $this->customer, [$this->price]);
138
        $futureSale = new Sale(null, $this->target, $this->customer, $plan, $this->time->add(new \DateInterval('P1M')));
139
        $action->setSale($futureSale);
140
141
        $charge = $this->calculator->calculateCharge($this->price, $action);
142
        $this->assertNull($charge);
143
    }
144
145
    public function testChargesForThisMonthAreNotCalculatedUntillDateOccurs()
146
    {
147
        $createChargeForSaleAt = function (DateTimeImmutable $time): ?Charge {
148
            $action = $this->createAction($this->prepaid->multiply(2));
149
150
            $plan = new Plan(null, '', $this->customer, [$this->price]);
151
            $futureSale = new Sale(null, $this->target, $this->customer, $plan, $time);
152
            $action->setSale($futureSale);
153
154
            return $this->calculator->calculateCharge($this->price, $action);
155
        };
156
157
        $notOccurredYet = $createChargeForSaleAt(
158
            // Sale is in future
159
            $this->time->add(new \DateInterval('PT1M'))
160
        );
161
        $this->assertNull($notOccurredYet);
162
163
        $occurred = $createChargeForSaleAt(
164
            // Sale is in past
165
            $this->time->sub(new \DateInterval('PT1M'))
166
        );
167
        $this->assertNotNull($occurred);
168
    }
169
170
    public function testGetHasSetId()
171
    {
172
        $this->expectException(CannotReassignException::class);
173
        $action = $this->createAction($this->prepaid->multiply(2));
174
        $this->assertFalse($action->hasId());
175
        $action->setId($this->testId);
176
        $this->assertTrue($action->hasId());
177
        $this->assertSame($this->testId, $action->getId());
178
        $action->setId((string) $this->testId);
179
        $this->assertSame($this->testId, $action->getId());
180
        $action->setId((int) $this->testId);
181
        $this->assertSame($this->testId, $action->getId());
182
        $action->setId('other id cannot be set');
183
    }
184
}
185