91 lines
3 KiB
PHP
91 lines
3 KiB
PHP
<?php
|
|
|
|
use App\Enums\SubscriptionPlan;
|
|
use App\Enums\SubscriptionStatus;
|
|
use App\Models\Subscription;
|
|
use App\Models\SubscriptionInvoice;
|
|
use App\Models\User;
|
|
use App\Notifications\SubscriptionActivatedNotification;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Notification;
|
|
|
|
beforeEach(function () {
|
|
config([
|
|
'services.moneybird.api_token' => 'test-token',
|
|
'services.moneybird.administration_id' => '123456',
|
|
'services.moneybird.webhook_token' => 'the-webhook-token',
|
|
]);
|
|
});
|
|
|
|
test('a request with the wrong webhook token is rejected', function () {
|
|
Http::fake();
|
|
|
|
$user = User::factory()->create();
|
|
Subscription::factory()->for($user)->starter()->create(['moneybird_contact_id' => 'contact-1']);
|
|
|
|
$this->post(route('webhooks.moneybird'), [
|
|
'webhook_token' => 'not-the-right-token',
|
|
'entity_type' => 'SalesInvoice',
|
|
'entity_id' => 'invoice-1',
|
|
])->assertForbidden();
|
|
|
|
Http::assertNothingSent();
|
|
});
|
|
|
|
test('a paid sales invoice activates the matching subscription', function () {
|
|
Notification::fake();
|
|
|
|
Http::fake([
|
|
'*/sales_invoices/invoice-1.json' => Http::response([
|
|
'id' => 'invoice-1',
|
|
'contact_id' => 'contact-1',
|
|
'state' => 'paid',
|
|
'invoice_date' => today()->toDateString(),
|
|
'due_date' => today()->addDays(14)->toDateString(),
|
|
'paid_at' => now()->toIso8601String(),
|
|
'total_price_excl_tax' => number_format(SubscriptionPlan::Starter->priceInCents() / 100, 2, '.', ''),
|
|
]),
|
|
]);
|
|
|
|
$user = User::factory()->create();
|
|
$subscription = Subscription::factory()->for($user)->starter()->create([
|
|
'moneybird_contact_id' => 'contact-1',
|
|
'status' => SubscriptionStatus::AwaitingPayment,
|
|
'current_period_starts_at' => today(),
|
|
'current_period_ends_at' => today()->addYear(),
|
|
]);
|
|
|
|
$this->post(route('webhooks.moneybird'), [
|
|
'webhook_token' => 'the-webhook-token',
|
|
'entity_type' => 'SalesInvoice',
|
|
'entity_id' => 'invoice-1',
|
|
])->assertNoContent();
|
|
|
|
expect($subscription->refresh()->status)->toBe(SubscriptionStatus::Active)
|
|
->and($subscription->grace_ends_at)->toBeNull();
|
|
|
|
$invoice = SubscriptionInvoice::sole();
|
|
expect($invoice->moneybird_invoice_id)->toBe('invoice-1')
|
|
->and($invoice->state)->toBe('paid')
|
|
->and($invoice->paid_at)->not->toBeNull();
|
|
|
|
Notification::assertSentTo($user, SubscriptionActivatedNotification::class);
|
|
});
|
|
|
|
test('an invoice for an unknown contact is ignored without error', function () {
|
|
Http::fake([
|
|
'*/sales_invoices/invoice-1.json' => Http::response([
|
|
'id' => 'invoice-1',
|
|
'contact_id' => 'someone-elses-contact',
|
|
'state' => 'paid',
|
|
]),
|
|
]);
|
|
|
|
$this->post(route('webhooks.moneybird'), [
|
|
'webhook_token' => 'the-webhook-token',
|
|
'entity_type' => 'SalesInvoice',
|
|
'entity_id' => 'invoice-1',
|
|
])->assertNoContent();
|
|
|
|
expect(SubscriptionInvoice::count())->toBe(0);
|
|
});
|