Skip to content

Commit 17d391f

Browse files
committed
test(enterprise): improve embeddable dashboard endpoint tests
- Remove 3 empty lines between test cases - Make Tallyman URL configurable via enterprise/coderd.Options - Add TallymanURL field as pre-parsed *url.URL - Pass through to tallymansdk.New for testing - Add comprehensive tests with httptest fake server: - Success: validates happy path with proper auth headers - WithColorOverrides: validates color override pass-through - UntrustedHostRejected: validates security check for non-metronome.com domains - TallymanServerError: validates error handling from Tallyman - InvalidDashboardType: validates invalid dashboard type returns 400 - Add dashboard type validation in handler - Use tallymansdk structs instead of map[string]interface{} in tests - Use assert instead of require in HTTP handlers (safe for non-test goroutines) - Simplify httptest.NewServer calls by using HandlerFunc directly - Make codersdk dashboard type an enum (UsageEmbeddableDashboardType) - Add nolint comments for owner user usage (required for license access) Made by cmux
1 parent f8ce104 commit 17d391f

File tree

10 files changed

+266
-20
lines changed

10 files changed

+266
-20
lines changed

coderd/apidoc/docs.go

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

codersdk/licenses.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,18 @@ func (c *Client) DeleteLicense(ctx context.Context, id int32) error {
135135
return nil
136136
}
137137

138+
// UsageEmbeddableDashboardType represents the type of usage dashboard to embed.
139+
type UsageEmbeddableDashboardType string
140+
141+
const (
142+
// UsageEmbeddableDashboardTypeUsage is the usage dashboard type.
143+
UsageEmbeddableDashboardTypeUsage UsageEmbeddableDashboardType = "usage"
144+
)
145+
138146
// GetUsageEmbeddableDashboardRequest is a request to get an embeddable dashboard URL.
139147
type GetUsageEmbeddableDashboardRequest struct {
140-
Dashboard string `json:"dashboard"`
141-
ColorOverrides []DashboardColorOverride `json:"color_overrides,omitempty"`
148+
Dashboard UsageEmbeddableDashboardType `json:"dashboard"`
149+
ColorOverrides []DashboardColorOverride `json:"color_overrides,omitempty"`
142150
}
143151

144152
// DashboardColorOverride represents a color override for a dashboard.

docs/reference/api/enterprise.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/api/schemas.md

Lines changed: 19 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

enterprise/coderd/coderd.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,9 @@ type Options struct {
671671
ProxyHealthInterval time.Duration
672672
LicenseKeys map[string]ed25519.PublicKey
673673

674+
// TallymanURL is the base URL for the Tallyman API. If nil, the default URL is used.
675+
TallymanURL *url.URL
676+
674677
// optional pre-shared key for authentication of external provisioner daemons
675678
ProvisionerDaemonPSK string
676679

enterprise/coderd/coderdenttest/coderdenttest.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"database/sql"
99
"io"
1010
"net/http"
11+
"net/url"
1112
"os/exec"
1213
"strings"
1314
"testing"
@@ -77,6 +78,7 @@ type Options struct {
7778
ReplicaErrorGracePeriod time.Duration
7879
ExternalTokenEncryption []dbcrypt.Cipher
7980
ProvisionerDaemonPSK string
81+
TallymanURL *url.URL
8082
}
8183

8284
// New constructs a codersdk client connected to an in-memory Enterprise API instance.
@@ -120,6 +122,7 @@ func NewWithAPI(t *testing.T, options *Options) (
120122
DefaultQuietHoursSchedule: oop.DeploymentValues.UserQuietHoursSchedule.DefaultSchedule.Value(),
121123
ProvisionerDaemonPSK: options.ProvisionerDaemonPSK,
122124
ExternalTokenEncryption: options.ExternalTokenEncryption,
125+
TallymanURL: options.TallymanURL,
123126
})
124127
require.NoError(t, err)
125128
setHandler(coderAPI.AGPL.RootHandler)

enterprise/coderd/licenses.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,16 @@ func (api *API) postUsageEmbeddableDashboard(rw http.ResponseWriter, r *http.Req
407407
return
408408
}
409409

410+
// Validate dashboard type. Currently only "usage" is supported,
411+
// but this may expand in the future.
412+
if req.Dashboard != codersdk.UsageEmbeddableDashboardTypeUsage {
413+
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
414+
Message: "Invalid dashboard type.",
415+
Detail: fmt.Sprintf("Dashboard type must be %q, got %q", codersdk.UsageEmbeddableDashboardTypeUsage, req.Dashboard),
416+
})
417+
return
418+
}
419+
410420
// Create tallyman client
411421
deploymentID, err := uuid.Parse(api.AGPL.DeploymentID)
412422
if err != nil {
@@ -421,6 +431,7 @@ func (api *API) postUsageEmbeddableDashboard(rw http.ResponseWriter, r *http.Req
421431
DB: api.Database,
422432
DeploymentID: deploymentID,
423433
LicenseKeys: api.LicenseKeys,
434+
BaseURL: api.TallymanURL,
424435
})
425436
if xerrors.Is(err, tallymansdk.ErrNoLicenseSupportsPublishing) {
426437
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{

0 commit comments

Comments
 (0)