Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Commit

Permalink
Usage Charge "ID on Null" Fix (#1210)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyon147 authored Oct 4, 2022
1 parent 00f5958 commit 7d27600
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 6 deletions.
23 changes: 20 additions & 3 deletions src/Traits/BillingController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
use Osiset\ShopifyApp\Actions\ActivatePlan;
use Osiset\ShopifyApp\Actions\ActivateUsageCharge;
use Osiset\ShopifyApp\Actions\GetPlanUrl;
use Osiset\ShopifyApp\Exceptions\ChargeNotRecurringException;
use Osiset\ShopifyApp\Exceptions\MissingShopDomainException;
use Osiset\ShopifyApp\Http\Requests\StoreUsageCharge;
use Osiset\ShopifyApp\Objects\Transfers\UsageChargeDetails as UsageChargeDetailsTransfer;
use Osiset\ShopifyApp\Objects\Values\ChargeReference;
use Osiset\ShopifyApp\Objects\Values\NullablePlanId;
use Osiset\ShopifyApp\Objects\Values\NullableShopDomain;
use Osiset\ShopifyApp\Objects\Values\PlanId;
use Osiset\ShopifyApp\Objects\Values\ShopDomain;
use Osiset\ShopifyApp\Storage\Queries\Shop as ShopQuery;
Expand Down Expand Up @@ -100,11 +103,25 @@ public function process(
*
* @param StoreUsageCharge $request The verified request.
* @param ActivateUsageCharge $activateUsageCharge The action for activating a usage charge.
* @param ShopQuery $shopQuery The shop querier.
*
* @throws MissingShopDomainException|ChargeNotRecurringException
*
* @return RedirectResponse
*/
public function usageCharge(StoreUsageCharge $request, ActivateUsageCharge $activateUsageCharge): RedirectResponse
{
public function usageCharge(
StoreUsageCharge $request,
ActivateUsageCharge $activateUsageCharge,
ShopQuery $shopQuery
): RedirectResponse {
$shopDomain = NullableShopDomain::fromNative($request->get('shop'));
// Get the shop from the shop param after it has been validated.
if ($shopDomain->isNull()) {
throw new MissingShopDomainException('Shop parameter is missing from request');
}
$shop = $shopQuery->getByDomain($shopDomain);

// Valid the request params.
$validated = $request->validated();

// Create the transfer object
Expand All @@ -113,7 +130,7 @@ public function usageCharge(StoreUsageCharge $request, ActivateUsageCharge $acti
$ucd->description = $validated['description'];

// Activate and save the usage charge
$activateUsageCharge($request->user()->getId(), $ucd);
$activateUsageCharge($shop->getId(), $ucd);

// All done, return with success
return isset($validated['redirect'])
Expand Down
85 changes: 82 additions & 3 deletions tests/Traits/BillingControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Osiset\ShopifyApp\Test\Traits;

use Illuminate\Auth\AuthManager;
use Osiset\ShopifyApp\Exceptions\MissingShopDomainException;
use Osiset\ShopifyApp\Storage\Models\Charge;
use Osiset\ShopifyApp\Storage\Models\Plan;
use Osiset\ShopifyApp\Test\Stubs\Api as ApiStub;
Expand Down Expand Up @@ -112,7 +113,7 @@ public function testUsageChargeSuccess(): void
$response = $this->call(
'post',
'/billing/usage-charge',
array_merge($data, ['signature' => $signature->toNative()])
array_merge($data, ['signature' => $signature->toNative(), 'shop' => $shop->name])
);
$response->assertRedirect($data['redirect']);
$response->assertSessionHas('success');
Expand All @@ -125,13 +126,13 @@ public function testUsageChargeSuccess(): void
$response = $this->call(
'post',
'/billing/usage-charge',
array_merge($data, ['signature' => $signature->toNative()])
array_merge($data, ['signature' => $signature->toNative(), 'shop' => $shop->name])
);
$response->assertRedirect('http://localhost');
$response->assertSessionHas('success');
}

public function testReturnToSettingScreenNoPlan()
public function testReturnToSettingScreenNoPlan(): void
{
// Set up a shop
$shop = factory($this->model)->create([
Expand All @@ -149,4 +150,82 @@ public function testReturnToSettingScreenNoPlan()
//Confirm we get sent back to the homepage of the app
$response->assertRedirect('https://example-app.com?shop='.$shop->name);
}

public function testUsageChargeSuccessWithShopParam(): void
{
// Stub the responses
ApiStub::stubResponses([
'post_recurring_application_charges_usage_charges_alt',
]);

// Create the shop
$plan = factory(Util::getShopifyConfig('models.plan', Plan::class))->states('type_recurring')->create();
$shop = factory($this->model)->create([
'plan_id' => $plan->getId()->toNative(),
]);
factory(Util::getShopifyConfig('models.charge', Charge::class))->states('type_recurring')->create([
'plan_id' => $plan->getId()->toNative(),
'user_id' => $shop->getId()->toNative(),
]);

// Login the shop
$this->auth->login($shop);

// Set up the data for the usage charge and the signature for it
$secret = $this->app['config']->get('shopify-app.api_secret');
$data = ['description' => 'One email', 'price' => 1.00, 'redirect' => 'https://localhost/usage-success'];
$signature = Util::createHmac(['data' => $data, 'buildQuery' => true], $secret);

// Run the call
$response = $this->call(
'post',
'/billing/usage-charge',
array_merge($data, ['signature' => $signature->toNative(), 'shop' => $shop->name])
);
$response->assertRedirect($data['redirect']);
$response->assertSessionHas('success');
$this->assertDatabaseHas('charges', ['description' => 'One email']);
}

public function testUsageChargeFailWithoutShopParam(): void
{
$this->withoutExceptionHandling();
$this->expectException(MissingShopDomainException::class);

// Stub the responses
ApiStub::stubResponses([
'post_recurring_application_charges_usage_charges_alt',
]);

// Create the shop
$plan = factory(Util::getShopifyConfig('models.plan', Plan::class))
->states('type_recurring')->create();
$shop = factory($this->model)->create([
'plan_id' => $plan->getId()->toNative(),
]);
factory(Util::getShopifyConfig('models.charge', Charge::class))
->states('type_recurring')->create([
'plan_id' => $plan->getId()->toNative(),
'user_id' => $shop->getId()->toNative(),
]);

// Login the shop
$this->auth->login($shop);

// Set up the data for the usage charge and the signature for it
$secret = $this->app['config']->get('shopify-app.api_secret');
$data = [
'description' => 'One email',
'price' => 1.00,
'redirect' => 'https://localhost/usage-success',];
$signature = Util::createHmac(['data' => $data, 'buildQuery' => true], $secret);

// Run the call
$response = $this->call(
'post',
'/billing/usage-charge',
array_merge($data, ['signature' => $signature->toNative()])
);
$this->assertDatabaseMissing('charges', ['description' => 'One email']);
}
}

0 comments on commit 7d27600

Please sign in to comment.