Skip to content
This repository has been archived by the owner on Jan 2, 2024. It is now read-only.

Commit

Permalink
api: expose Trial and End on /v1/phase response (#273)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmizerany authored Mar 3, 2023
1 parent ffb064e commit f26506a
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 5 deletions.
9 changes: 8 additions & 1 deletion api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"net/http"
"strings"
"time"

"github.com/kr/pretty"
"golang.org/x/exp/slices"
Expand Down Expand Up @@ -327,13 +328,19 @@ func (h *Handler) servePhase(w http.ResponseWriter, r *http.Request) error {

h.Logf("lookup phases: %# v", pretty.Formatter(ps))

for _, p := range ps {
for i, p := range ps {
if p.Current {
var end time.Time
if i+1 < len(ps) {
end = ps[i+1].Effective
}
return httpJSON(w, apitypes.PhaseResponse{
Effective: p.Effective,
End: end,
Features: p.Features,
Plans: p.Plans,
Fragments: p.Fragments(),
Trial: p.Trial,
})
}
}
Expand Down
81 changes: 81 additions & 0 deletions api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,87 @@ func TestPhaseBadOrg(t *testing.T) {
})
}

func TestPhase(t *testing.T) {
t.Parallel()

now := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)

ctx := context.Background()
tc := newTestClient(t)

ctx, err := tc.WithClock(ctx, t.Name(), now)
if err != nil {
t.Fatal(err)
}

m := []byte(`
{"plans": {"plan:test@0": {"features": {"feature:x": {}}}}}
`)

_, err = tc.PushJSON(ctx, m)
if err != nil {
t.Fatal(err)
}

cases := []struct {
phases []tier.Phase
want apitypes.PhaseResponse
}{
{
phases: []tier.Phase{{
Trial: true,
Features: []string{"plan:test@0"},
}, {
Effective: now.AddDate(0, 0, 14),
Trial: false,
Features: []string{"plan:test@0"},
}},
want: apitypes.PhaseResponse{
Effective: now,
End: now.AddDate(0, 0, 14),
Features: mpfs("feature:x@plan:test@0"),
Plans: mpps("plan:test@0"),
Trial: true,
},
},
{
phases: []tier.Phase{{
Features: []string{"plan:test@0"},
}},
want: apitypes.PhaseResponse{
Effective: now,
Features: mpfs("feature:x@plan:test@0"),
Plans: mpps("plan:test@0"),
},
},
{
phases: []tier.Phase{{
Trial: true,
Features: []string{"plan:test@0"},
}},
want: apitypes.PhaseResponse{
Trial: true,
Effective: now,
Features: mpfs("feature:x@plan:test@0"),
Plans: mpps("plan:test@0"),
},
},
}

for _, tt := range cases {
t.Run("", func(t *testing.T) {
if _, err := tc.Schedule(ctx, "org:test", &tier.ScheduleParams{Phases: tt.phases}); err != nil {
t.Fatal(err)
}
got, err := tc.LookupPhase(ctx, "org:test")
if err != nil {
t.Fatal(err)
}
diff.Test(t, t.Errorf, got, tt.want)
})
}
}

func TestPhaseFragments(t *testing.T) {
t.Parallel()

Expand Down
2 changes: 2 additions & 0 deletions api/apitypes/apitypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ type Phase struct {

type PhaseResponse struct {
Effective time.Time `json:"effective,omitempty"`
End time.Time `json:"end,omitempty"`
Features []refs.FeaturePlan `json:"features,omitempty"`
Plans []refs.Plan `json:"plans,omitempty"`
Fragments []refs.FeaturePlan `json:"fragments,omitempty"`
Trial bool `json:"trial,omitempty"`
}

type PaymentMethodsResponse struct {
Expand Down
7 changes: 5 additions & 2 deletions control/schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,9 @@ type stripeSubSchedule struct {
Metadata struct {
Name string `json:"tier.subscription"`
}
Start int64 `json:"start_date"`
Items []struct {
Start int64 `json:"start_date"`
TrialEnd int64 `json:"trial_end"`
Items []struct {
Price stripePrice
}
}
Expand Down Expand Up @@ -317,6 +318,8 @@ func (c *Client) lookupPhases(ctx context.Context, org string, s subscription, n
Current: p.Start == ss.Current.Start,

Plans: plans,

Trial: p.TrialEnd > 0,
}
all = append(all, p)
if p.Current {
Expand Down
67 changes: 65 additions & 2 deletions control/schedule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,51 @@ func TestSchedule(t *testing.T) {
})
}

func TestScheduleTrial(t *testing.T) {
s := newScheduleTester(t)

model := []Feature{{
FeaturePlan: mpf("feature:x@plan:free@0"),
Interval: "@monthly",
Currency: "usd",
}}

fps := FeaturePlans(model)
s.push(model)

s.schedule("org:example", 14, "", fps...)
s.checkPhases("org:example", []Phase{
{
Org: "org:example",
Current: true,
Effective: t0, // unchanged by advanced clock
Features: FeaturePlans(model),
Plans: plans("plan:free@0"),
Trial: true,
},
{
Org: "org:example",
Current: false,
Effective: t0.AddDate(0, 0, 14), // unchanged by advanced clock
Features: FeaturePlans(model),
Plans: plans("plan:free@0"),
Trial: false,
},
})

s.schedule("org:example", -1, "", fps...)
s.checkPhases("org:example", []Phase{
{
Org: "org:example",
Current: true,
Effective: t0, // unchanged by advanced clock
Features: FeaturePlans(model),
Plans: plans("plan:free@0"),
Trial: true,
},
})
}

type scheduleTester struct {
ctx context.Context
t *testing.T
Expand Down Expand Up @@ -203,7 +248,7 @@ func (s *scheduleTester) schedule(org string, trialDays int, payment string, fs
Trial: true,
Features: fs,
}, {
Effective: t0.AddDate(0, 1, 0),
Effective: t0.AddDate(0, 0, trialDays),
Features: fs,
}}
}
Expand All @@ -216,6 +261,16 @@ func (s *scheduleTester) schedule(org string, trialDays int, payment string, fs
}
}

func (s *scheduleTester) checkPhases(org string, want []Phase) {
s.t.Helper()
got, err := s.cc.LookupPhases(s.ctx, org)
if err != nil {
s.t.Fatal(err)
}
s.t.Logf("got phases %# v", pretty.Formatter(got))
diff.Test(s.t, s.t.Errorf, got, want, ignoreProviderIDs)
}

func (s *scheduleTester) report(org, name string, n int) {
s.t.Helper()
if err := s.cc.ReportUsage(s.ctx, org, mpn(name), Report{
Expand Down Expand Up @@ -315,7 +370,15 @@ func TestScheduleFreeTrials(t *testing.T) {

s.checkInvoices("org:trial", []Invoice{{
Lines: []InvoiceLineItem{
lineItem(featureX, 2, 0),
lineItem(featureX, 1, 1),
},
SubtotalPreTax: 1,
Subtotal: 1,
TotalPreTax: 1,
Total: 1,
}, {
Lines: []InvoiceLineItem{
lineItem(featureX, 1, 0),
},
}, {
Lines: []InvoiceLineItem{
Expand Down

0 comments on commit f26506a

Please sign in to comment.