256 lines
7.5 KiB
Go
256 lines
7.5 KiB
Go
// SPDX-Licence-Identifier: EUPL-1.2
|
|
|
|
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"io/fs"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
coreapi "dappco.re/go/core/api"
|
|
"dappco.re/go/core/build/internal/ax"
|
|
"dappco.re/go/core/build/pkg/build"
|
|
"dappco.re/go/core/io"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestProvider_BuildProviderIdentity_Good(t *testing.T) {
|
|
p := NewProvider(".", nil)
|
|
|
|
assert.Equal(t, "build", p.Name())
|
|
assert.Equal(t, "/api/v1/build", p.BasePath())
|
|
}
|
|
|
|
func TestProvider_BuildProviderElement_Good(t *testing.T) {
|
|
p := NewProvider(".", nil)
|
|
el := p.Element()
|
|
|
|
assert.Equal(t, "core-build-panel", el.Tag)
|
|
assert.Equal(t, "/assets/core-build.js", el.Source)
|
|
}
|
|
|
|
func TestProvider_BuildProviderChannels_Good(t *testing.T) {
|
|
p := NewProvider(".", nil)
|
|
channels := p.Channels()
|
|
|
|
assert.Contains(t, channels, "build.started")
|
|
assert.Contains(t, channels, "build.complete")
|
|
assert.Contains(t, channels, "build.failed")
|
|
assert.Contains(t, channels, "release.started")
|
|
assert.Contains(t, channels, "release.complete")
|
|
assert.Contains(t, channels, "sdk.generated")
|
|
assert.Len(t, channels, 6)
|
|
}
|
|
|
|
func TestProvider_BuildProviderDescribe_Good(t *testing.T) {
|
|
p := NewProvider(".", nil)
|
|
routes := p.Describe()
|
|
|
|
// Should have 10 endpoint descriptions
|
|
assert.Len(t, routes, 10)
|
|
|
|
// Verify key routes exist
|
|
paths := make(map[string]string)
|
|
for _, r := range routes {
|
|
paths[r.Path] = r.Method
|
|
}
|
|
|
|
assert.Equal(t, "GET", paths["/config"])
|
|
assert.Equal(t, "GET", paths["/discover"])
|
|
assert.Equal(t, "POST", paths["/build"])
|
|
assert.Equal(t, "GET", paths["/artifacts"])
|
|
assert.Equal(t, "GET", paths["/release/version"])
|
|
assert.Equal(t, "GET", paths["/release/changelog"])
|
|
assert.Equal(t, "POST", paths["/release"])
|
|
assert.Equal(t, "POST", paths["/release/workflow"])
|
|
assert.Equal(t, "GET", paths["/sdk/diff"])
|
|
assert.Equal(t, "POST", paths["/sdk/generate"])
|
|
|
|
var workflowRoute *coreapi.RouteDescription
|
|
for i := range routes {
|
|
if routes[i].Path == "/release/workflow" {
|
|
workflowRoute = &routes[i]
|
|
break
|
|
}
|
|
}
|
|
|
|
require.NotNil(t, workflowRoute)
|
|
require.NotNil(t, workflowRoute.RequestBody)
|
|
|
|
properties, ok := workflowRoute.RequestBody["properties"].(map[string]any)
|
|
require.True(t, ok)
|
|
|
|
pathSchema, ok := properties["path"].(map[string]any)
|
|
require.True(t, ok)
|
|
assert.Equal(t, "string", pathSchema["type"])
|
|
assert.Equal(t, "Output path for the workflow file, relative to the project directory or absolute.", pathSchema["description"])
|
|
}
|
|
|
|
func TestProvider_BuildProviderDefaultProjectDir_Good(t *testing.T) {
|
|
p := NewProvider("", nil)
|
|
assert.Equal(t, ".", p.projectDir)
|
|
}
|
|
|
|
func TestProvider_BuildProviderCustomProjectDir_Good(t *testing.T) {
|
|
p := NewProvider("/tmp/myproject", nil)
|
|
assert.Equal(t, "/tmp/myproject", p.projectDir)
|
|
}
|
|
|
|
func TestProvider_BuildProviderNilHub_Good(t *testing.T) {
|
|
p := NewProvider(".", nil)
|
|
// emitEvent should not panic with nil hub
|
|
p.emitEvent("build.started", map[string]any{"test": true})
|
|
}
|
|
|
|
func TestProvider_GetBuilderSupportedTypes_Good(t *testing.T) {
|
|
cases := []struct {
|
|
projectType build.ProjectType
|
|
name string
|
|
}{
|
|
{build.ProjectTypeGo, "go"},
|
|
{build.ProjectTypeWails, "wails"},
|
|
{build.ProjectTypeNode, "node"},
|
|
{build.ProjectTypePHP, "php"},
|
|
{build.ProjectTypePython, "python"},
|
|
{build.ProjectTypeRust, "rust"},
|
|
{build.ProjectTypeDocs, "docs"},
|
|
{build.ProjectTypeCPP, "cpp"},
|
|
{build.ProjectTypeDocker, "docker"},
|
|
{build.ProjectTypeLinuxKit, "linuxkit"},
|
|
{build.ProjectTypeTaskfile, "taskfile"},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
t.Run(string(tc.projectType), func(t *testing.T) {
|
|
b, err := getBuilder(tc.projectType)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tc.name, b.Name())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestProvider_GetBuilderUnsupportedType_Bad(t *testing.T) {
|
|
_, err := getBuilder(build.ProjectType("unknown"))
|
|
assert.ErrorIs(t, err, fs.ErrNotExist)
|
|
}
|
|
|
|
func TestProvider_BuildProviderResolveDir_Good(t *testing.T) {
|
|
p := NewProvider("/tmp", nil)
|
|
dir, err := p.resolveDir()
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "/tmp", dir)
|
|
}
|
|
|
|
func TestProvider_BuildProviderResolveDirRelative_Good(t *testing.T) {
|
|
p := NewProvider(".", nil)
|
|
dir, err := p.resolveDir()
|
|
require.NoError(t, err)
|
|
// Should return an absolute path
|
|
assert.True(t, len(dir) > 1 && dir[0] == '/')
|
|
}
|
|
|
|
func TestProvider_BuildProviderMediumSet_Good(t *testing.T) {
|
|
p := NewProvider(".", nil)
|
|
assert.NotNil(t, p.medium, "medium should be set to io.Local")
|
|
}
|
|
|
|
func TestProvider_ResolveProjectType_Good(t *testing.T) {
|
|
t.Run("honours explicit build type override", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
require.NoError(t, ax.WriteFile(ax.Join(dir, "go.mod"), []byte("module example"), 0o644))
|
|
|
|
projectType, err := resolveProjectType(io.Local, dir, "docker")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, build.ProjectTypeDocker, projectType)
|
|
})
|
|
|
|
t.Run("falls back to detection when build type is empty", func(t *testing.T) {
|
|
dir := t.TempDir()
|
|
require.NoError(t, ax.WriteFile(ax.Join(dir, "go.mod"), []byte("module example"), 0o644))
|
|
|
|
projectType, err := resolveProjectType(io.Local, dir, "")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, build.ProjectTypeGo, projectType)
|
|
})
|
|
}
|
|
|
|
func TestProvider_GenerateReleaseWorkflow_Good(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
projectDir := t.TempDir()
|
|
p := NewProvider(projectDir, nil)
|
|
|
|
recorder := httptest.NewRecorder()
|
|
request := httptest.NewRequest(http.MethodPost, "/release/workflow", bytes.NewBufferString(`{}`))
|
|
request.Header.Set("Content-Type", "application/json")
|
|
|
|
ctx, _ := gin.CreateTestContext(recorder)
|
|
ctx.Request = request
|
|
|
|
p.generateReleaseWorkflow(ctx)
|
|
|
|
assert.Equal(t, http.StatusOK, recorder.Code)
|
|
|
|
path := build.ReleaseWorkflowPath(projectDir)
|
|
content, err := io.Local.Read(path)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, content, "workflow_call:")
|
|
assert.Contains(t, content, "workflow_dispatch:")
|
|
}
|
|
|
|
func TestProvider_GenerateReleaseWorkflow_CustomPath_Good(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
projectDir := t.TempDir()
|
|
p := NewProvider(projectDir, nil)
|
|
|
|
recorder := httptest.NewRecorder()
|
|
request := httptest.NewRequest(http.MethodPost, "/release/workflow", bytes.NewBufferString(`{"path":"ci/release.yml"}`))
|
|
request.Header.Set("Content-Type", "application/json")
|
|
|
|
ctx, _ := gin.CreateTestContext(recorder)
|
|
ctx.Request = request
|
|
|
|
p.generateReleaseWorkflow(ctx)
|
|
|
|
assert.Equal(t, http.StatusOK, recorder.Code)
|
|
|
|
path := ax.Join(projectDir, "ci", "release.yml")
|
|
content, err := io.Local.Read(path)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, content, "workflow_call:")
|
|
assert.Contains(t, content, "workflow_dispatch:")
|
|
}
|
|
|
|
func TestProvider_DiscoverProject_Good(t *testing.T) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
projectDir := t.TempDir()
|
|
require.NoError(t, ax.WriteFile(ax.Join(projectDir, "go.mod"), []byte("module example"), 0o644))
|
|
require.NoError(t, ax.MkdirAll(ax.Join(projectDir, "frontend"), 0o755))
|
|
require.NoError(t, ax.WriteFile(ax.Join(projectDir, "frontend", "package.json"), []byte("{}"), 0o644))
|
|
|
|
p := NewProvider(projectDir, nil)
|
|
|
|
recorder := httptest.NewRecorder()
|
|
request := httptest.NewRequest(http.MethodGet, "/discover", nil)
|
|
|
|
ctx, _ := gin.CreateTestContext(recorder)
|
|
ctx.Request = request
|
|
|
|
p.discoverProject(ctx)
|
|
|
|
assert.Equal(t, http.StatusOK, recorder.Code)
|
|
body := recorder.Body.String()
|
|
assert.Contains(t, body, `"types":["go","node"]`)
|
|
assert.Contains(t, body, `"primary":"go"`)
|
|
assert.Contains(t, body, `"has_frontend":true`)
|
|
assert.Contains(t, body, `"has_subtree_npm":true`)
|
|
assert.Contains(t, body, `"go.mod":true`)
|
|
assert.Contains(t, body, `"frontend/package.json":true`)
|
|
}
|