From 1486b52727f04f174de532f91e47c364b89377a7 Mon Sep 17 00:00:00 2001 From: Yader Velasquez Date: Wed, 14 Feb 2024 17:57:39 -0600 Subject: [PATCH] Add more tests to analytics and billing --- analytics/routes_test.go | 54 ++++++++++- analytics/samples/analytics.json | 68 ++++++++++++++ billing/routes_test.go | 40 ++++++++ billing/samples/get_checkout_session.json | 74 +++++++++++++++ billing/samples/invoice_list.json | 108 ++++++++++++++++++++++ 5 files changed, 343 insertions(+), 1 deletion(-) create mode 100644 analytics/samples/analytics.json create mode 100644 billing/samples/get_checkout_session.json create mode 100644 billing/samples/invoice_list.json diff --git a/analytics/routes_test.go b/analytics/routes_test.go index a2eb971..0dfd80a 100644 --- a/analytics/routes_test.go +++ b/analytics/routes_test.go @@ -1,6 +1,7 @@ package analytics_test import ( + "fmt" "links/analytics" "links/cmd" "links/models" @@ -11,13 +12,64 @@ import ( "time" "git.sr.ht/~emersion/gqlclient" + "github.com/jarcoal/httpmock" + "github.com/labstack/echo/v4" "github.com/stretchr/testify/require" oauth2 "netlandish.com/x/gobwebs-oauth2" "netlandish.com/x/gobwebs/crypto" "netlandish.com/x/gobwebs/server" ) -func TestHandlers(t *testing.T) { +func TestHandler(t *testing.T) { + c := require.New(t) + srv, e := cmd.NewWebTestServer(t) + cmd.RunMigrations(t, srv.DB) + analyticsService := analytics.NewService(e.Group("/analytics")) + user := cmd.NewTestUser(1, false, false, true, true) + defer srv.Shutdown() + go srv.Run() + dbCtx := cmd.NewDBContext(srv.DB, "America/Managua") + + httpmock.Activate() + defer httpmock.DeactivateAndReset() + jsonResponse, err := httpmock.NewJsonResponder(http.StatusOK, httpmock.File("samples/analytics.json")) + c.NoError(err) + httpmock.RegisterResponder("POST", "http://127.0.0.1:8080/query", jsonResponse) + + t.Run("checkout success", func(t *testing.T) { + short := &models.LinkShort{ + Title: "Testing short", + URL: "http://testing.com", + ShortCode: "abc", + OrgID: 1, + UserID: int(user.ID), + DomainID: 1, + } + err := short.Store(dbCtx) + c.NoError(err) + req := httptest.NewRequest(http.MethodGet, "/", nil) + + // Add fake analytics entries + err = analytics.AddAnalytics(dbCtx, req, short.ID, analytics.LinkShortAnalyticsFilter, "") + c.NoError(err) + request := httptest.NewRequest(http.MethodGet, "/shorts/1", nil) + request.Header.Set(echo.HeaderContentType, echo.MIMEApplicationForm) + recorder := httptest.NewRecorder() + ctx := &server.Context{ + Server: srv, + Context: e.NewContext(request, recorder), + User: user, + } + ctx.SetPath("/:slug/analytics/:type/:id") + ctx.SetParamNames("slug", "type", "id") + ctx.SetParamValues("personal-org", "shorts", fmt.Sprint(short.ID)) + err = cmd.MakeRequest(srv, analyticsService.Detail, ctx) + c.NoError(err) + c.Equal(http.StatusOK, recorder.Code) + }) +} + +func TestAPI(t *testing.T) { c := require.New(t) srv, e, entropy := cmd.NewAPITestServer(t) cmd.RunMigrations(t, srv.DB) diff --git a/analytics/samples/analytics.json b/analytics/samples/analytics.json new file mode 100644 index 0000000..5bb0dfa --- /dev/null +++ b/analytics/samples/analytics.json @@ -0,0 +1,68 @@ +{ + "data": { + "analytics": { + "title": "New Listst", + "clicksOverTime": [ + { + "key": "2024-01-21", + "val": 10 + }, + { + "key": "2024-01-28", + "val": 10 + }, + { + "key": "2024-02-04", + "val": 10 + }, + { + "key": "2024-02-11", + "val": 10 + }, + { + "key": "2024-01-14", + "val": 10 + } + ], + "listingLink": [ + { + "id": 12, + "title": "Title", + "clicks": 12 + } + ], + "qrList": [ + { + "id": 12, + "title": "Title", + "clicks": 12 + } + ], + "clicksCountry": [ + { + "key": "Country", + "val": 1000 + } + ], + "clicksCity": [ + { + "key": "City", + "val": 1000 + } + + ], + "clicksDevice": [ + { + "key": "Device", + "val": 1000 + } + ], + "clicksReferrer": [ + { + "key": "Referrer", + "val": 1000 + } + ] + } + } +} diff --git a/billing/routes_test.go b/billing/routes_test.go index 80c645c..5c009dd 100644 --- a/billing/routes_test.go +++ b/billing/routes_test.go @@ -30,6 +30,46 @@ func TestHandlers(t *testing.T) { go srv.Run() dbCtx := cmd.NewDBContext(srv.DB, "America/Managua") + t.Run("checkout success", func(t *testing.T) { + httpmock.Activate() + defer httpmock.DeactivateAndReset() + checkoutSession, err := httpmock.NewJsonResponder(http.StatusOK, httpmock.File("samples/get_checkout_session.json")) + c.NoError(err) + httpmock.RegisterResponder("GET", "https://api.stripe.com/v1/checkout/sessions/sid", checkoutSession) + + invoiceList, err := httpmock.NewJsonResponder(http.StatusOK, httpmock.File("samples/invoice_list.json")) + c.NoError(err) + httpmock.RegisterResponder("GET", "https://api.stripe.com/v1/invoices", invoiceList) + + request := httptest.NewRequest(http.MethodGet, "/sucess?session_id=sid", nil) + request.Header.Set(echo.HeaderContentType, echo.MIMEApplicationForm) + recorder := httptest.NewRecorder() + ctx := &server.Context{ + Server: srv, + Context: e.NewContext(request, recorder), + User: user, + } + ctx.SetPath("/success") + err = cmd.MakeRequest(srv, billingService.CheckoutSuccess, ctx) + c.NoError(err) + c.Equal(http.StatusOK, recorder.Code) + }) + + t.Run("checkou cancel", func(t *testing.T) { + request := httptest.NewRequest(http.MethodGet, "/cancel", nil) + request.Header.Set(echo.HeaderContentType, echo.MIMEApplicationForm) + recorder := httptest.NewRecorder() + ctx := &server.Context{ + Server: srv, + Context: e.NewContext(request, recorder), + User: user, + } + ctx.SetPath("/cancel") + err := cmd.MakeRequest(srv, billingService.CheckoutCancel, ctx) + c.NoError(err) + c.Equal(http.StatusOK, recorder.Code) + }) + t.Run("create subscription", func(t *testing.T) { httpmock.Activate() defer httpmock.DeactivateAndReset() diff --git a/billing/samples/get_checkout_session.json b/billing/samples/get_checkout_session.json new file mode 100644 index 0000000..1e21bd4 --- /dev/null +++ b/billing/samples/get_checkout_session.json @@ -0,0 +1,74 @@ +{ + "id": "cs_test_a11YYufWQzNY63zpQ6QSNRQhkUpVph4WRmzW0zWJO2znZKdVujZ0N0S22u", + "object": "checkout.session", + "after_expiration": null, + "allow_promotion_codes": null, + "amount_subtotal": 2198, + "amount_total": 2198, + "automatic_tax": { + "enabled": false, + "liability": null, + "status": null + }, + "billing_address_collection": null, + "cancel_url": null, + "client_reference_id": null, + "consent": null, + "consent_collection": null, + "created": 1679600215, + "currency": "usd", + "custom_fields": [], + "custom_text": { + "shipping_address": null, + "submit": null + }, + "customer": null, + "customer_creation": "if_required", + "customer_details": null, + "customer_email": null, + "expires_at": 1679686615, + "invoice": null, + "invoice_creation": { + "enabled": false, + "invoice_data": { + "account_tax_ids": null, + "custom_fields": null, + "description": null, + "footer": null, + "issuer": null, + "metadata": {}, + "rendering_options": null + } + }, + "livemode": false, + "locale": null, + "metadata": {}, + "mode": "payment", + "payment_intent": null, + "payment_link": null, + "payment_method_collection": "always", + "payment_method_options": {}, + "payment_method_types": [ + "card" + ], + "payment_status": "unpaid", + "phone_number_collection": { + "enabled": false + }, + "recovered_from": null, + "setup_intent": null, + "shipping_address_collection": null, + "shipping_cost": null, + "shipping_details": null, + "shipping_options": [], + "status": "open", + "submit_type": null, + "subscription": "12332", + "success_url": "https://example.com/success", + "total_details": { + "amount_discount": 0, + "amount_shipping": 0, + "amount_tax": 0 + }, + "url": "https://checkout.stripe.com/c/pay/cs_test_a11YYufWQzNY63zpQ6QSNRQhkUpVph4WRmzW0zWJO2znZKdVujZ0N0S22u#fidkdWxOYHwnPyd1blpxYHZxWjA0SDdPUW5JbmFMck1wMmx9N2BLZjFEfGRUNWhqTmJ%2FM2F8bUA2SDRySkFdUV81T1BSV0YxcWJcTUJcYW5rSzN3dzBLPUE0TzRKTTxzNFBjPWZEX1NKSkxpNTVjRjN8VHE0YicpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl" +} diff --git a/billing/samples/invoice_list.json b/billing/samples/invoice_list.json new file mode 100644 index 0000000..5cca9ed --- /dev/null +++ b/billing/samples/invoice_list.json @@ -0,0 +1,108 @@ +{ + "object": "list", + "url": "/v1/invoices", + "has_more": false, + "data": [ + { + "id": "in_1MtHbELkdIwHu7ixl4OzzPMv", + "object": "invoice", + "account_country": "US", + "account_name": "Stripe Docs", + "account_tax_ids": null, + "amount_due": 0, + "amount_paid": 0, + "amount_remaining": 0, + "amount_shipping": 0, + "application": null, + "application_fee_amount": null, + "attempt_count": 0, + "attempted": false, + "auto_advance": false, + "automatic_tax": { + "enabled": false, + "liability": null, + "status": null + }, + "billing_reason": "manual", + "charge": null, + "collection_method": "charge_automatically", + "created": 1680644467, + "currency": "usd", + "custom_fields": null, + "customer": "cus_NeZwdNtLEOXuvB", + "customer_address": null, + "customer_email": "jennyrosen@example.com", + "customer_name": "Jenny Rosen", + "customer_phone": null, + "customer_shipping": null, + "customer_tax_exempt": "none", + "customer_tax_ids": [], + "default_payment_method": null, + "default_source": null, + "default_tax_rates": [], + "description": null, + "discount": null, + "discounts": [], + "due_date": null, + "ending_balance": null, + "footer": null, + "from_invoice": null, + "hosted_invoice_url": null, + "invoice_pdf": null, + "issuer": { + "type": "self" + }, + "last_finalization_error": null, + "latest_revision": null, + "lines": { + "object": "list", + "data": [], + "has_more": false, + "total_count": 0, + "url": "/v1/invoices/in_1MtHbELkdIwHu7ixl4OzzPMv/lines" + }, + "livemode": false, + "metadata": {}, + "next_payment_attempt": null, + "number": null, + "on_behalf_of": null, + "paid": false, + "paid_out_of_band": false, + "payment_intent": null, + "payment_settings": { + "default_mandate": null, + "payment_method_options": null, + "payment_method_types": null + }, + "period_end": 1680644467, + "period_start": 1680644467, + "post_payment_credit_notes_amount": 0, + "pre_payment_credit_notes_amount": 0, + "quote": null, + "receipt_number": null, + "rendering_options": null, + "shipping_cost": null, + "shipping_details": null, + "starting_balance": 0, + "statement_descriptor": null, + "status": "draft", + "status_transitions": { + "finalized_at": null, + "marked_uncollectible_at": null, + "paid_at": null, + "voided_at": null + }, + "subscription": null, + "subtotal": 0, + "subtotal_excluding_tax": 0, + "tax": null, + "test_clock": null, + "total": 0, + "total_discount_amounts": [], + "total_excluding_tax": 0, + "total_tax_amounts": [], + "transfer_data": null, + "webhooks_delivered_at": 1680644467 + } + ] +} -- 2.45.2