154 lines
4.1 KiB
Go
154 lines
4.1 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"scout/internal/registry"
|
|
)
|
|
|
|
func TestProjectRoutesKeepSamePackageNamesIsolated(t *testing.T) {
|
|
root := t.TempDir()
|
|
legacy, err := registry.New(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
projects, err := registry.NewProjectRegistry(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, _, err := projects.Ensure("ssl", "SSL", "证书项目"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, _, err := projects.Ensure("smail", "Smail", "邮件项目"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
server := httptest.NewServer((&Server{
|
|
Registry: legacy,
|
|
Projects: projects,
|
|
DeveloperToken: "test-token",
|
|
AllowLegacyToken: true,
|
|
}).Handler())
|
|
defer server.Close()
|
|
|
|
uploadProjectPackage(t, server.URL, "ssl", "shared", "1.0.0", "ssl-content")
|
|
uploadProjectPackage(t, server.URL, "smail", "shared", "1.0.0", "smail-content")
|
|
|
|
assertProjectPackageContent(t, server.URL+"/api/v1/projects/ssl/packages/shared/1.0.0/download?platform=linux&architecture=amd64", "ssl-content")
|
|
assertProjectPackageContent(t, server.URL+"/api/v1/projects/smail/packages/shared/1.0.0/download?platform=linux&architecture=amd64", "smail-content")
|
|
|
|
response, err := http.Get(server.URL + "/api/v1/projects")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer response.Body.Close()
|
|
var listed struct {
|
|
Projects []registry.Project `json:"projects"`
|
|
}
|
|
if err := json.NewDecoder(response.Body).Decode(&listed); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if response.StatusCode != http.StatusOK || len(listed.Projects) != 3 {
|
|
t.Fatalf("项目列表错误:%d %+v", response.StatusCode, listed.Projects)
|
|
}
|
|
}
|
|
|
|
func uploadProjectPackage(t *testing.T, baseURL, project, name, version, content string) {
|
|
t.Helper()
|
|
body := &bytes.Buffer{}
|
|
writer := multipart.NewWriter(body)
|
|
for key, value := range map[string]string{
|
|
"name": name,
|
|
"version": version,
|
|
"platform": "linux",
|
|
"architecture": "amd64",
|
|
"status": "published",
|
|
} {
|
|
if err := writer.WriteField(key, value); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
file, err := writer.CreateFormFile("file", name+"-"+version+".pkg")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := file.Write([]byte(content)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := writer.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
request, err := http.NewRequest(http.MethodPost, baseURL+"/api/v1/projects/"+project+"/packages/upload", body)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
request.Header.Set("Content-Type", writer.FormDataContentType())
|
|
request.Header.Set("Authorization", "Bearer test-token")
|
|
response, err := http.DefaultClient.Do(request)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer response.Body.Close()
|
|
if response.StatusCode != http.StatusCreated {
|
|
data, _ := io.ReadAll(response.Body)
|
|
t.Fatalf("项目上传失败:%d %s", response.StatusCode, data)
|
|
}
|
|
}
|
|
|
|
func assertProjectPackageContent(t *testing.T, endpoint, expected string) {
|
|
t.Helper()
|
|
response, err := http.Get(endpoint)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer response.Body.Close()
|
|
data, err := io.ReadAll(response.Body)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if response.StatusCode != http.StatusOK || string(data) != expected {
|
|
t.Fatalf("项目包内容错误:%d %q", response.StatusCode, data)
|
|
}
|
|
}
|
|
|
|
func TestProjectRouteRejectsDisabledProject(t *testing.T) {
|
|
root := t.TempDir()
|
|
legacy, err := registry.New(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
projects, err := registry.NewProjectRegistry(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, _, err := projects.Ensure("ssl", "SSL", "证书项目"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := projects.Update("ssl", registry.Project{
|
|
Name: "SSL",
|
|
Description: "已停用",
|
|
Status: "disabled",
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
server := httptest.NewServer((&Server{
|
|
Registry: legacy,
|
|
Projects: projects,
|
|
}).Handler())
|
|
defer server.Close()
|
|
|
|
response, err := http.Get(server.URL + "/api/v1/projects/ssl/packages")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer response.Body.Close()
|
|
if response.StatusCode != http.StatusForbidden {
|
|
t.Fatalf("停用项目应禁止访问:%d", response.StatusCode)
|
|
}
|
|
}
|