sdk/artifact/artifacts_test.go
Louis Seubert 0f40c0b375
All checks were successful
default / ensure tests work (push) Successful in 28s
feat: artifacts client
2026-09-13 10:53:42 +02:00

182 lines
5.3 KiB
Go

package artifact
import (
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
type capturedRequest struct {
path string
auth string
body []byte
}
func newTestServer(t *testing.T, status int, contentType, response string) (*httptest.Server, *capturedRequest) {
t.Helper()
got := &capturedRequest{}
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
got.path = r.URL.Path
got.auth = r.Header.Get("Authorization")
got.body, _ = io.ReadAll(r.Body)
w.Header().Set("content-type", contentType)
w.WriteHeader(status)
_, _ = io.WriteString(w, response)
}))
t.Cleanup(server.Close)
return server, got
}
func TestClient_CreateArtifact(t *testing.T) {
t.Parallel()
server, got := newTestServer(t, http.StatusOK, "application/json",
`{"ok":true,"signedUploadUrl":"https://example.test/upload"}`)
c := NewClient(server.URL, "secret")
res, err := c.CreateArtifact(context.Background(), CreateArtifactRequest{RunID: "run", JobRunID: "job", Name: "foo", Version: 4})
if err != nil {
t.Fatal(err)
}
if !res.Ok || res.SignedUploadUrl != "https://example.test/upload" {
t.Errorf("unexpected response: %+v", res)
}
if got, want := got.path, "/twirp/github.actions.results.api.v1.ArtifactService/CreateArtifact"; got != want {
t.Errorf("expected path %q to be %q", got, want)
}
if got, want := got.auth, "Bearer secret"; got != want {
t.Errorf("expected Authorization %q to be %q", got, want)
}
var req CreateArtifactRequest
if err := json.Unmarshal(got.body, &req); err != nil {
t.Fatal(err)
}
if req != (CreateArtifactRequest{RunID: "run", JobRunID: "job", Name: "foo", Version: 4}) {
t.Errorf("unexpected request: %+v", req)
}
}
func TestClient_FinalizeArtifact(t *testing.T) {
t.Parallel()
server, got := newTestServer(t, http.StatusOK, "application/json",
`{"ok":true,"artifactId":"42"}`)
c := NewClient(server.URL, "secret")
res, err := c.FinalizeArtifact(context.Background(), FinalizeArtifactRequest{RunID: "run", JobRunID: "job", Name: "foo", Size: 10, Hash: "abc"})
if err != nil {
t.Fatal(err)
}
if !res.Ok || res.ArtifactId != "42" {
t.Errorf("unexpected response: %+v", res)
}
if got, want := got.path, "/twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact"; got != want {
t.Errorf("expected path %q to be %q", got, want)
}
var req FinalizeArtifactRequest
if err := json.Unmarshal(got.body, &req); err != nil {
t.Fatal(err)
}
if req.Size != 10 || req.Hash != "abc" {
t.Errorf("unexpected request: %+v", req)
}
}
func TestClient_ListArtifacts(t *testing.T) {
t.Parallel()
server, got := newTestServer(t, http.StatusOK, "application/json",
`{"artifacts":[{"databaseId":"7","name":"foo"}]}`)
c := NewClient(server.URL, "secret")
res, err := c.ListArtifacts(context.Background(), ListArtifactsRequest{NameFilter: "foo"})
if err != nil {
t.Fatal(err)
}
if len(res.Artifacts) != 1 || res.Artifacts[0].Id != "7" || res.Artifacts[0].Name != "foo" {
t.Errorf("unexpected response: %+v", res)
}
if got, want := got.path, "/twirp/github.actions.results.api.v1.ArtifactService/ListArtifacts"; got != want {
t.Errorf("expected path %q to be %q", got, want)
}
}
func TestClient_GetSignedArtifactURL(t *testing.T) {
t.Parallel()
server, got := newTestServer(t, http.StatusOK, "application/json",
`{"signedUrl":"https://example.test/download"}`)
c := NewClient(server.URL, "secret")
res, err := c.GetSignedArtifactURL(context.Background(), GetSignedArtifactURLRequest{RunID: "run", JobRunID: "job", Name: "foo"})
if err != nil {
t.Fatal(err)
}
if res.SignedUrl != "https://example.test/download" {
t.Errorf("unexpected response: %+v", res)
}
if got, want := got.path, "/twirp/github.actions.results.api.v1.ArtifactService/GetSignedArtifactURL"; got != want {
t.Errorf("expected path %q to be %q", got, want)
}
}
func TestClient_DeleteArtifact(t *testing.T) {
t.Parallel()
server, got := newTestServer(t, http.StatusOK, "application/json",
`{"ok":true,"artifactId":"7"}`)
c := NewClient(server.URL, "secret")
res, err := c.DeleteArtifact(context.Background(), DeleteArtifactRequest{RunID: "run", JobRunID: "job", Name: "foo"})
if err != nil {
t.Fatal(err)
}
if !res.Ok || res.ArtifactId != "7" {
t.Errorf("unexpected response: %+v", res)
}
if got, want := got.path, "/twirp/github.actions.results.api.v1.ArtifactService/DeleteArtifact"; got != want {
t.Errorf("expected path %q to be %q", got, want)
}
}
func TestClient_twirp(t *testing.T) {
t.Parallel()
cases := []struct {
name string
status int
contentType string
body string
wantErr string
}{
{"bad content type", http.StatusOK, "text/plain", "nope", "content-type"},
{"server error", http.StatusInternalServerError, "application/json", `{"message":"boom"}`, "twirp call"},
{"bad json", http.StatusOK, "application/json", "{", "unexpected EOF"},
}
for _, tc := range cases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
server, _ := newTestServer(t, tc.status, tc.contentType, tc.body)
c := NewClient(server.URL, "secret")
_, err := c.CreateArtifact(context.Background(), CreateArtifactRequest{Name: "foo"})
if err == nil || !strings.Contains(err.Error(), tc.wantErr) {
t.Errorf("expected error containing %q, got %v", tc.wantErr, err)
}
})
}
}