@@ -7,8 +7,10 @@ import {
7
7
createItem ,
8
8
createUser ,
9
9
createVote ,
10
+ getUser ,
10
11
type Item ,
11
12
listItemsByUser ,
13
+ User ,
12
14
Vote ,
13
15
} from "@/utils/db.ts" ;
14
16
import { genNewItem , genNewUser , genNewVote } from "@/utils/db_test.ts" ;
@@ -23,7 +25,12 @@ import {
23
25
assertObjectMatch ,
24
26
assertStringIncludes ,
25
27
} from "std/assert/mod.ts" ;
26
- import { assertSpyCall , resolvesNext , stub } from "std/testing/mock.ts" ;
28
+ import {
29
+ assertSpyCall ,
30
+ resolvesNext ,
31
+ returnsNext ,
32
+ stub ,
33
+ } from "std/testing/mock.ts" ;
27
34
import Stripe from "stripe" ;
28
35
import options from "./fresh.config.ts" ;
29
36
@@ -463,6 +470,27 @@ Deno.test("[e2e] POST /api/items/[id]/vote", async (test) => {
463
470
} ) ;
464
471
} ) ;
465
472
473
+ function createStripeEvent (
474
+ type : Stripe . Event . Type ,
475
+ customer : string ,
476
+ ) : Promise < Stripe . Event > {
477
+ return Promise . resolve ( {
478
+ id : "123" ,
479
+ object : "event" ,
480
+ api_version : null ,
481
+ created : 0 ,
482
+ livemode : false ,
483
+ pending_webhooks : 0 ,
484
+ type,
485
+ request : null ,
486
+ data : {
487
+ object : {
488
+ customer,
489
+ } ,
490
+ } ,
491
+ } ) ;
492
+ }
493
+
466
494
Deno . test ( "[e2e] POST /api/stripe-webhooks" , async ( test ) => {
467
495
const url = "http://localhost/api/stripe-webhooks" ;
468
496
@@ -517,6 +545,135 @@ Deno.test("[e2e] POST /api/stripe-webhooks", async (test) => {
517
545
) ;
518
546
assertEquals ( resp . status , Status . BadRequest ) ;
519
547
} ) ;
548
+
549
+ await test . step ( "returns HTTP 404 Not Found response if the user is not found for subscription creation" , async ( ) => {
550
+ const constructEventAsyncStub = stub (
551
+ stripe . webhooks ,
552
+ "constructEventAsync" ,
553
+ returnsNext ( [
554
+ createStripeEvent ( "customer.subscription.created" , "x" ) ,
555
+ ] ) ,
556
+ ) ;
557
+
558
+ const resp = await handler (
559
+ new Request ( url , {
560
+ method : "POST" ,
561
+ headers : { "Stripe-Signature" : crypto . randomUUID ( ) } ,
562
+ } ) ,
563
+ ) ;
564
+
565
+ assertFalse ( resp . ok ) ;
566
+ assertEquals ( await resp . text ( ) , "User not found" ) ;
567
+ assertEquals ( resp . status , Status . NotFound ) ;
568
+
569
+ constructEventAsyncStub . restore ( ) ;
570
+ } ) ;
571
+
572
+ await test . step ( "returns HTTP 201 Created response if the subscription is created" , async ( ) => {
573
+ const user = genNewUser ( ) ;
574
+ await createUser ( user ) ;
575
+
576
+ const constructEventAsyncStub = stub (
577
+ stripe . webhooks ,
578
+ "constructEventAsync" ,
579
+ returnsNext ( [
580
+ createStripeEvent (
581
+ "customer.subscription.created" ,
582
+ user . stripeCustomerId ! ,
583
+ ) ,
584
+ ] ) ,
585
+ ) ;
586
+
587
+ const resp = await handler (
588
+ new Request ( url , {
589
+ method : "POST" ,
590
+ headers : { "Stripe-Signature" : crypto . randomUUID ( ) } ,
591
+ } ) ,
592
+ ) ;
593
+
594
+ assertEquals ( await getUser ( user . login ) , { ...user , isSubscribed : true } ) ;
595
+ assert ( resp . ok ) ;
596
+ assertEquals ( resp . body , null ) ;
597
+ assertEquals ( resp . status , Status . Created ) ;
598
+
599
+ constructEventAsyncStub . restore ( ) ;
600
+ } ) ;
601
+
602
+ await test . step ( "returns HTTP 404 Not Found response if the user is not found for subscription deletion" , async ( ) => {
603
+ const constructEventAsyncStub = stub (
604
+ stripe . webhooks ,
605
+ "constructEventAsync" ,
606
+ returnsNext ( [
607
+ createStripeEvent ( "customer.subscription.deleted" , "x" ) ,
608
+ ] ) ,
609
+ ) ;
610
+
611
+ const resp = await handler (
612
+ new Request ( url , {
613
+ method : "POST" ,
614
+ headers : { "Stripe-Signature" : crypto . randomUUID ( ) } ,
615
+ } ) ,
616
+ ) ;
617
+
618
+ assertFalse ( resp . ok ) ;
619
+ assertEquals ( await resp . text ( ) , "User not found" ) ;
620
+ assertEquals ( resp . status , Status . NotFound ) ;
621
+
622
+ constructEventAsyncStub . restore ( ) ;
623
+ } ) ;
624
+
625
+ await test . step ( "returns HTTP 202 Accepted response if the subscription is deleted" , async ( ) => {
626
+ const user : User = { ...genNewUser ( ) , isSubscribed : true } ;
627
+ await createUser ( user ) ;
628
+
629
+ const constructEventAsyncStub = stub (
630
+ stripe . webhooks ,
631
+ "constructEventAsync" ,
632
+ returnsNext ( [
633
+ createStripeEvent (
634
+ "customer.subscription.deleted" ,
635
+ user . stripeCustomerId ! ,
636
+ ) ,
637
+ ] ) ,
638
+ ) ;
639
+
640
+ const resp = await handler (
641
+ new Request ( url , {
642
+ method : "POST" ,
643
+ headers : { "Stripe-Signature" : crypto . randomUUID ( ) } ,
644
+ } ) ,
645
+ ) ;
646
+
647
+ assertEquals ( await getUser ( user . login ) , { ...user , isSubscribed : false } ) ;
648
+ assert ( resp . ok ) ;
649
+ assertEquals ( resp . body , null ) ;
650
+ assertEquals ( resp . status , Status . Accepted ) ;
651
+
652
+ constructEventAsyncStub . restore ( ) ;
653
+ } ) ;
654
+
655
+ await test . step ( "returns HTTP 400 Bad Request response if the event type is not supported" , async ( ) => {
656
+ const constructEventAsyncStub = stub (
657
+ stripe . webhooks ,
658
+ "constructEventAsync" ,
659
+ returnsNext ( [
660
+ createStripeEvent ( "account.application.authorized" , "x" ) ,
661
+ ] ) ,
662
+ ) ;
663
+
664
+ const resp = await handler (
665
+ new Request ( url , {
666
+ method : "POST" ,
667
+ headers : { "Stripe-Signature" : crypto . randomUUID ( ) } ,
668
+ } ) ,
669
+ ) ;
670
+
671
+ assertFalse ( resp . ok ) ;
672
+ assertEquals ( await resp . text ( ) , "Event type not supported" ) ;
673
+ assertEquals ( resp . status , Status . BadRequest ) ;
674
+
675
+ constructEventAsyncStub . restore ( ) ;
676
+ } ) ;
520
677
} ) ;
521
678
522
679
Deno . test ( "[e2e] GET /account" , async ( test ) => {
0 commit comments