Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create commerce context #8

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@
},
"require": {
"drupal/drupal-extension": "^4.0 || ^5.0"
},
"require-dev": {
"drupal/commerce": "*"
}
}
131 changes: 131 additions & 0 deletions src/CommerceContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php

namespace Frontkom\DrupalBehatDefinitions;

use Behat\Gherkin\Node\TableNode;
use Drupal\DrupalExtension\Context\RawDrupalContext;
use Drupal\commerce_product\ProductVariationStorageInterface;
use Drupal\commerce_promotion\Entity\PromotionInterface;

/**
* Class CommerceContext.
*
* Provide Behat step-definitions for common Commerce functionalities.
*/
class CommerceContext extends EntityContextBase {

/**
* Generate coupons.
*
* @Given coupons:
*/
public function createCoupons(TableNode $nodesTable) {
$storage = \Drupal::entityTypeManager()->getStorage('commerce_promotion_coupon');
foreach ($nodesTable->getHash() as $nodeHash) {
$coupon = (object) $nodeHash;
$promotion = $this->getPromotionByName($coupon->promotion);

$coupon_saved = $this->couponCreate($coupon);
$coupon_loaded = $storage->load($coupon_saved->id);
$promotion->get('coupons')->appendItem($coupon_loaded);
$promotion->save();
}
}

/**
* Load promotion by name.
*/
public function getPromotionByName($name) {
$storage = \Drupal::entityTypeManager()->getStorage('commerce_promotion');
$promotions = $storage->loadByProperties(['name' => $name]);

if (count($promotions) !== 1) {
throw new \Exception('Expected 1 promotion with title ' . $name . ' but found ' . count($promotions));
}

return reset($promotions);
}

/**
* Create coupon.
*/
public function couponCreate($coupon) {
$saved = $this->getDriver()->createEntity('commerce_promotion_coupon', $coupon);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this make them automatically deleted after the scenario?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'm pretty sure of that. I checked the db records for commerce_promotion_coupon get cleared after a scenario with creating coupons

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am now 100% sure that is not the case.

The entities are probably randomly deleted only because they are tied to a promotion deleted in the same cleanup. But there is nothing in our test classes or drupal extension to clean it up. We should do that here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be as easy as append it to $this->entities though

return $saved;
}

/**
* Visit promotion edit page.
*
* @Then I visit promotion :name edit page
*/
public function iVisitPromotionEditPage($name) {
$promotion = $this->getPromotionByName($name);
$this->getSession()->visit($this->locatePath($promotion->toUrl('edit-form')->toString()));
}

/**
* Check if product variation exist.
*
* @Then /^a product with SKU "([^"]*)" should exist$/
*/
public function aProductWithSkuShouldExist($sku) {
/** @var \Drupal\commerce_product\ProductVariationStorageInterface $variation_storage */
$variation_storage = \Drupal::entityTypeManager()->getStorage('commerce_product_variation');
adamsokolowski06 marked this conversation as resolved.
Show resolved Hide resolved
$product_variations = $variation_storage->loadBySku($sku);
if (empty($product_variations)) {
throw new \Exception('No variation found with SKU ' . $sku);
}
}

/**
* Set records DB for exchange rates.
*
* Valid for commerce_exchanger^2, because in version 1 the exchange rates are in config.
*
* @Given I set :value exchange rates
*/
public function setManualExchangeRates($value) {
$currency_storage = \Drupal::service('entity_type.manager')->getStorage('commerce_currency');
$currencies = $currency_storage->loadMultiple();
$currencies = array_keys($currencies);
$database = \Drupal::database();
$time = time();

foreach ($currencies as $currency) {
$query = $database->insert('commerce_exchanger_latest_rates')
->fields([
'exchanger',
'source',
'target',
'value',
'timestamp',
'manual',
]);

$query->values([
'exchanger' => 'manual',
'source' => $currency,
'target' => 'NOK',
'value' => $value,
'timestamp' => $time,
// A weird value just to identify records to remove in AfterScenario.
'manual' => '666666',
]);
$query->execute();
}
}

/**
* Remove exchange rates.
*
* @AfterScenario
*/
public function cleanExchangeRates() {
$database = \Drupal::database();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to either be wrapped in some conditional to check if the database table exists or wrapped in try/catch. This is not default commerce, and can be disabled on sites.

$database->delete('commerce_exchanger_latest_rates')
->condition('manual', '666666', '=')
->execute();
}

}
48 changes: 48 additions & 0 deletions src/EntityContextBase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Frontkom\DrupalBehatDefinitions;

use Drupal\DrupalExtension\Context\RawDrupalContext;

/**
* Class EntityContextBase.
*
* It is supposed to be extended by classes which implement creating entities. It automatically cleans up
* all the entities created during a single test.
*/
abstract class EntityContextBase extends RawDrupalContext {

/**
* An array of entites created in the context.
*
* @var array
*/
protected $entites = [];

/**
* Remove entities by names.
*
* @Then I remove entities of type :entity_type_id with names :names
*/
public function iRemoveEntities($entity_type_id, $names) {
$entities = \Drupal::entityTypeManager()->getStorage($entity_type_id)
->loadByProperties([
'name' => explode(', ', $names),
]);
foreach ($entities as $entity) {
$entity->delete();
}
}

/**
* Clean up created entities.
*
* @AfterScenario
*/
public function cleanUpEntities() {
foreach ($this->entites as $entity) {
$entity->delete();
}
}

}
Loading