Completed
Push — master ( be22d6...2445b3 )
by Will
23s
created

tests/php/Cart/ShoppingCartControllerTest.php (1 issue)

1
<?php
2
3
namespace SilverShop\Tests\Cart;
4
5
use SilverShop\Cart\ShoppingCart;
6
use SilverShop\Cart\ShoppingCartController;
7
use SilverShop\Model\Variation\Variation;
8
use SilverShop\Page\Product;
9
use SilverShop\Tests\Model\Product\CustomProduct_OrderItem;
10
use SilverShop\Tests\ShopTest;
11
use SilverStripe\Core\Config\Config;
12
use SilverStripe\Dev\FunctionalTest;
13
use SilverStripe\Security\SecurityToken;
14
15
/**
16
 * @link ShoppingCart_Controller
17
 *
18
 * Test manipulating via urls.
19
 */
20
class ShoppingCartControllerTest extends FunctionalTest
21
{
22
    public static $fixture_file = __DIR__ . '/../Fixtures/shop.yml';
23
24
    public static $disable_theme = true;
25
    protected static $use_draft_site = false;
26
    protected $autoFollowRedirection = false;
27
28
    // This seems to be required, because we query the OrderItem table and thus this gets included…
29
    // TODO: Remove once we figure out how to circumvent that…
30
    protected static $extra_dataobjects = [
31
        CustomProduct_OrderItem::class,
32
    ];
33
34
    /**
35
     * @var Product
36
     */
37
    protected $mp3player;
38
39
    /**
40
     * @var Product
41
     */
42
    protected $socks;
43
44
    /**
45
     * @var Product
46
     */
47
    protected $noPurchaseProduct;
48
49
    /**
50
     * @var Product
51
     */
52
    protected $draftProduct;
53
54
    /**
55
     * @var Product
56
     */
57
    protected $noPriceProduct;
58
59
    /**
60
     * @var ShoppingCart
61
     */
62
    protected $cart;
63
64
65
    public function setUp()
66
    {
67
        parent::setUp();
68
69
        ShopTest::setConfiguration(); //reset config
70
        ShoppingCart::singleton()->clear();
71
72
        // Needed, so that products can be published
73
        $this->logInWithPermission('ADMIN');
74
75
        $this->mp3player = $this->objFromFixture(Product::class, 'mp3player');
76
        $this->socks = $this->objFromFixture(Product::class, 'socks');
77
        //products that can't be purchased
78
        $this->noPurchaseProduct = $this->objFromFixture(Product::class, 'beachball');
79
        $this->draftProduct = $this->objFromFixture(Product::class, 'tshirt');
80
        $this->noPriceProduct = $this->objFromFixture(Product::class, 'hdtv');
81
82
        //publish some products
83
        $this->mp3player->publishSingle();
84
        $this->socks->publishSingle();
85
        $this->noPurchaseProduct->publishSingle();
86
        $this->noPriceProduct->publishSingle();
87
88
        $this->cart = ShoppingCart::singleton();
89
    }
90
91
    public function testAddToCart()
92
    {
93
        // add 2 of the same items via url
94
        $this->get(ShoppingCartController::add_item_link($this->mp3player)); //add item via url
95
        $this->get(ShoppingCartController::add_item_link($this->mp3player)); //add another
96
        $this->get(ShoppingCartController::add_item_link($this->socks)); //add a different product
97
        $this->get(ShoppingCartController::add_item_link($this->noPurchaseProduct));  //add a product that you can't add
98
        $this->get(ShoppingCartController::add_item_link($this->draftProduct));  //add a product that is draft
99
        $this->get(ShoppingCartController::add_item_link($this->noPriceProduct));  //add a product that has no price
100
101
        // See what's in the cart
102
        $items = ShoppingCart::curr()->Items();
103
        $this->assertNotNull($items);
104
105
        $this->assertEquals($items->Count(), 2, 'There are 2 items in the cart');
106
        //join needed to provide ProductID
107
        $mp3playeritem = $items
108
            ->innerJoin("SilverShop_Product_OrderItem", "\"SilverShop_OrderItem\".\"ID\" = \"SilverShop_Product_OrderItem\".\"ID\"")
109
            ->find('ProductID', $this->mp3player->ID);
110
111
        $this->assertNotNull($mp3playeritem, "Mp3 player is in cart");
112
113
        // We have the product that we asserted in our fixture file, with a quantity of 2 in the cart
114
        $this->assertEquals(
115
            $mp3playeritem->ProductID,
116
            $this->mp3player->ID,
117
            'We have the correct Product ID in the cart.'
118
        );
119
        $this->assertEquals($mp3playeritem->Quantity, 2, 'We have 2 of this product in the cart.');
120
121
        // set item quantiy
122
        $this->get(
123
            ShoppingCartController::set_quantity_item_link($this->mp3player, array('quantity' => 5))
124
        ); //add item via url
125
        $items = ShoppingCart::curr()->Items();
126
        $mp3playeritem =
127
            $items->innerJoin("SilverShop_Product_OrderItem", "\"SilverShop_OrderItem\".\"ID\" = \"SilverShop_Product_OrderItem\".\"ID\"")->find(
128
                'ProductID',
129
                $this->mp3player->ID
130
            ); //join needed to provide ProductID
131
        $this->assertEquals($mp3playeritem->Quantity, 5, 'We have 5 of this product in the cart.');
132
133
        // non purchasable product checks
134
        $this->assertEquals(
135
            $this->noPurchaseProduct->canPurchase(),
136
            false,
137
            'non-purcahseable product is not purchaseable'
138
        );
139
        $this->assertArrayNotHasKey(
140
            $this->noPurchaseProduct->ID,
141
            $items->map('ProductID')->toArray(),
142
            'non-purcahable product is not in cart'
143
        );
144
        $this->assertEquals($this->draftProduct->canPurchase(), true, 'draft products can be purchased');
145
        $this->assertArrayNotHasKey(
146
            $this->draftProduct->ID,
147
            $items->map('ProductID')->toArray(),
148
            'draft product is not in cart'
149
        );
150
        $this->assertEquals($this->noPriceProduct->canPurchase(), false, 'product without price is not purchaseable');
151
        $this->assertArrayNotHasKey(
152
            $this->noPriceProduct->ID,
153
            $items->map('ProductID')->toArray(),
154
            'product without price is not in cart'
155
        );
156
157
        $this->cart->clear();
158
    }
159
160
    public function testRemoveFromCart()
161
    {
162
163
        // add items via url
164
        $this->get(ShoppingCartController::set_quantity_item_link($this->mp3player, array('quantity' => 5)));
165
        $this->assertTrue($this->cart->get($this->mp3player) !== false, "mp3player item now exists in cart");
166
        $this->get(ShoppingCartController::add_item_link($this->socks));
167
        $this->assertTrue($this->cart->get($this->socks) !== false, "socks item now exists in cart");
168
169
        // remove items via url
170
        $this->get(ShoppingCartController::remove_item_link($this->socks)); //remove one different = remove completely
171
        $this->assertFalse((bool)$this->cart->get($this->socks));
172
173
        $this->get(ShoppingCartController::remove_item_link($this->mp3player)); //remove one product = 4 left
174
175
        $mp3playeritem = $this->cart->get($this->mp3player);
176
        $this->assertNotNull($mp3playeritem, "product still exists");
177
        $this->assertEquals($mp3playeritem->Quantity, 4, "only 4 of item left");
178
179
        $items = ShoppingCart::curr()->Items();
180
        $this->assertNotNull($items, "Cart is not empty");
181
182
        $this->cart->clear(); //test clearing cart
183
        $this->assertEquals(
184
            ShoppingCart::curr(),
185
            null,
186
            'Cart is clear'
187
        ); //items is a databoject set, and will therefore be null when cart is empty.
188
    }
189
190
    public function testVariations()
191
    {
192
        $this->loadFixture(__DIR__ . '/../Fixtures/variations.yml');
0 ignored issues
show
Deprecated Code introduced by
The function SilverStripe\Dev\SapphireTest::loadFixture() has been deprecated: 4.0...5.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

192
        /** @scrutinizer ignore-deprecated */ $this->loadFixture(__DIR__ . '/../Fixtures/variations.yml');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
193
        /**
194
         * @var Product $ballRoot
195
         */
196
        $ballRoot = $this->objFromFixture(Product::class, 'ball');
197
        $ballRoot->publishSingle();
198
        /**
199
         * @var Product $ball1
200
         */
201
        $ball1 = $this->objFromFixture(Variation::class, 'redlarge');
202
        /**
203
         * @var Product $ball2
204
         */
205
        $ball2 = $this->objFromFixture(Variation::class, 'redsmall');
206
207
        $this->logInWithPermission('ADMIN');
208
        $ball1->publishSingle();
209
        $ball2->publishSingle();
210
211
        // Add the two variation items
212
        $this->get(ShoppingCartController::add_item_link($ball1));
213
        $this->get(ShoppingCartController::add_item_link($ball2));
214
        $items = ShoppingCart::curr()->Items();
215
        $this->assertNotNull($items);
216
        $this->assertEquals($items->Count(), 2, 'There are 2 items in the cart');
217
218
        // Remove one and see what happens
219
        $this->get(ShoppingCartController::remove_all_item_link($ball1));
220
        $this->assertEquals($items->Count(), 1, 'There is 1 item in the cart');
221
        $this->assertFalse((bool)$this->cart->get($ball1), "first item not in cart");
222
        $this->assertNotNull($this->cart->get($ball2), "second item is in cart");
223
    }
224
225
    public function testSecurityToken()
226
    {
227
        $enabled = SecurityToken::is_enabled();
228
        // enable security tokens
229
        SecurityToken::enable();
230
231
        $productId = $this->mp3player->ID;
232
        // link should contain the security-token
233
        $link = ShoppingCartController::add_item_link($this->mp3player);
234
        $this->assertRegExp('{^shoppingcart/add/SilverShop-Page-Product/' . $productId . '\?SecurityID=[a-f0-9]+$}', $link);
235
236
        // should redirect back to the shop
237
        $response = $this->get($link);
238
        $this->assertEquals($response->getStatusCode(), 302);
239
240
        // disable security token for cart-links
241
        Config::modify()->set(ShoppingCartController::class, 'disable_security_token', true);
242
243
        $link = ShoppingCartController::add_item_link($this->mp3player);
244
        $this->assertEquals('shoppingcart/add/SilverShop-Page-Product/' . $productId, $link);
245
246
        // should redirect back to the shop
247
        $response = $this->get($link);
248
        $this->assertEquals($response->getStatusCode(), 302);
249
250
        SecurityToken::disable();
251
252
        Config::modify()->set(ShoppingCartController::class, 'disable_security_token', false);
253
        $link = ShoppingCartController::add_item_link($this->mp3player);
254
        $this->assertEquals('shoppingcart/add/SilverShop-Page-Product/' . $productId, $link);
255
256
        // should redirect back to the shop
257
        $response = $this->get($link);
258
        $this->assertEquals($response->getStatusCode(), 302);
259
260
        SecurityToken::enable();
261
        // should now return a 400 status
262
        $response = $this->get($link);
263
        $this->assertEquals($response->getStatusCode(), 400);
264
265
        // restore previous setting
266
        if (!$enabled) {
267
            SecurityToken::disable();
268
        }
269
    }
270
}
271