Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions internal/api/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,11 +421,11 @@ func TestFunctionMethodsUseGeneratedRoutes(t *testing.T) {
var body map[string]any
require.NoError(t, json.NewDecoder(r.Body).Decode(&body))
logSearchBodies = append(logSearchBodies, body)
if len(logSearchBodies) == 1 {
writeAPIJSON(t, w, http.StatusOK, logsResponse("function runtime"))
if logSearchIsBuild(body) {
writeAPIJSON(t, w, http.StatusOK, logsResponse("deployment build"))
return
}
writeAPIJSON(t, w, http.StatusOK, logsResponse("deployment build"))
writeAPIJSON(t, w, http.StatusOK, logsResponse("function runtime"))
case r.Method == http.MethodGet && r.URL.Path == "/projects/"+projectIDText+"/functions/"+functionIDText+"/schedulers":
writeAPIJSON(t, w, http.StatusOK, map[string]any{
"data": []any{functionSchedulerResponse(schedulerIDText, functionIDText, projectIDText, "hello scheduler", true)},
Expand Down Expand Up @@ -720,6 +720,18 @@ func functionDeploymentResponse(id, projectID, functionID string) map[string]any
}
}

// logSearchIsBuild reports whether a captured /logs/search request body targets
// build logs (carries a deployment selector) rather than runtime logs. Routing
// stub responses on request content is more robust than relying on call order.
func logSearchIsBuild(body map[string]any) bool {
resource, ok := body["resource"].(map[string]any)
if !ok {
return false
}
_, hasDeployments := resource["deployments"]
return hasDeployments
}

func logsResponse(message string) map[string]any {
return map[string]any{
"data": []any{
Expand Down
6 changes: 3 additions & 3 deletions internal/api/frontends_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ func TestFrontendDomainAndLogsMethodsUseGeneratedRoutes(t *testing.T) {
var body map[string]any
require.NoError(t, json.NewDecoder(r.Body).Decode(&body))
logSearchBodies = append(logSearchBodies, body)
if len(logSearchBodies) == 1 {
writeAPIJSON(t, w, http.StatusOK, logsResponse("frontend runtime"))
if logSearchIsBuild(body) {
writeAPIJSON(t, w, http.StatusOK, logsResponse("frontend build"))
return
}
writeAPIJSON(t, w, http.StatusOK, logsResponse("frontend build"))
writeAPIJSON(t, w, http.StatusOK, logsResponse("frontend runtime"))
case r.Method == http.MethodPost && r.URL.Path == "/projects/"+projectIDText+"/frontends/"+frontendIDText+"/domain":
require.NoError(t, json.NewDecoder(r.Body).Decode(&createBody))
writeAPIJSON(t, w, http.StatusCreated, frontendCustomDomainResponse("app.example.com", "provisioning"))
Expand Down
7 changes: 7 additions & 0 deletions internal/api/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ const (
logResourceTypeFunction = "function"
)

// logSearchRequest is a hand-marshalled body for POST /projects/{id}/logs/search,
// sent via SearchProjectLogsWithBodyWithResponse rather than the typed
// SearchProjectLogsWithResponse. The generated apiclient models the request's
// `resource` selector as an oapi-codegen oneOf union (apiclient.LogRequestResource),
// built through From.../As... accessors; this flat struct produces the identical
// wire format while keeping the call sites readable. Intentional — do not
// "simplify" it back to the typed union call.
Comment on lines +20 to +26
type logSearchRequest struct {
Resource logRequestResource `json:"resource"`
Limit *int `json:"limit,omitempty"`
Expand Down
Loading