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
|
|||
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 |
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.