Skip to content

Commit f62abc2

Browse files
feat: added mock server tests
1 parent c439ed6 commit f62abc2

File tree

11 files changed

+396
-3
lines changed

11 files changed

+396
-3
lines changed

internal/mocktest/mocktest.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package mocktest
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net"
7+
"net/http"
8+
"net/url"
9+
"os"
10+
"os/exec"
11+
"path/filepath"
12+
"runtime"
13+
"strings"
14+
"testing"
15+
"time"
16+
17+
"github.com/stretchr/testify/assert"
18+
"github.com/stretchr/testify/require"
19+
)
20+
21+
var mockServerURL *url.URL
22+
23+
func init() {
24+
mockServerURL, _ = url.Parse("http://localhost:4010")
25+
if testURL := os.Getenv("TEST_API_BASE_URL"); testURL != "" {
26+
if parsed, err := url.Parse(testURL); err == nil {
27+
mockServerURL = parsed
28+
}
29+
}
30+
}
31+
32+
// OnlyMockServerDialer only allows network connections to the mock server
33+
type OnlyMockServerDialer struct{}
34+
35+
func (d *OnlyMockServerDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
36+
if address == mockServerURL.Host {
37+
return (&net.Dialer{}).DialContext(ctx, network, address)
38+
}
39+
40+
return nil, fmt.Errorf("BLOCKED: connection to %s not allowed (only allowed: %s)", address, mockServerURL.Host)
41+
}
42+
43+
func blockNetworkExceptMockServer() (http.RoundTripper, http.RoundTripper) {
44+
restricted := &http.Transport{
45+
DialContext: (&OnlyMockServerDialer{}).DialContext,
46+
}
47+
48+
origClient, origDefault := http.DefaultClient.Transport, http.DefaultTransport
49+
http.DefaultClient.Transport, http.DefaultTransport = restricted, restricted
50+
return origClient, origDefault
51+
}
52+
53+
func restoreNetwork(origClient, origDefault http.RoundTripper) {
54+
http.DefaultClient.Transport, http.DefaultTransport = origClient, origDefault
55+
}
56+
57+
// TestRunMockTestWithFlags runs a test against a mock server with the provided
58+
// CLI flags and ensures it succeeds
59+
func TestRunMockTestWithFlags(t *testing.T, flags ...string) {
60+
origClient, origDefault := blockNetworkExceptMockServer()
61+
defer restoreNetwork(origClient, origDefault)
62+
63+
// Check if mock server is running
64+
conn, err := net.DialTimeout("tcp", mockServerURL.Host, 2*time.Second)
65+
if err != nil {
66+
require.Fail(t, "Mock server is not running on "+mockServerURL.Host+". Please start the mock server before running tests.")
67+
} else {
68+
conn.Close()
69+
}
70+
71+
// Get the path to the main command
72+
_, filename, _, ok := runtime.Caller(0)
73+
require.True(t, ok, "Could not get current file path")
74+
dirPath := filepath.Dir(filename)
75+
project := filepath.Join(dirPath, "..", "..", "cmd", "...")
76+
77+
args := []string{"run", project, "--base-url", mockServerURL.String()}
78+
args = append(args, flags...)
79+
80+
t.Logf("Testing command: stl %s", strings.Join(args[4:], " "))
81+
82+
cmd := exec.Command("go", args...)
83+
output, err := cmd.CombinedOutput()
84+
if err != nil {
85+
assert.Fail(t, "Test failed", "Error: %v\nOutput: %s", err, output)
86+
}
87+
88+
t.Logf("Test passed successfully with output:\n%s\n", output)
89+
}
90+
91+
func TestFile(t *testing.T, contents string) string {
92+
tmpDir := t.TempDir()
93+
filename := filepath.Join(tmpDir, "file.txt")
94+
require.NoError(t, os.WriteFile(filename, []byte(contents), 0644))
95+
return filename
96+
}

internal/requestflag/requestflag.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ func (d *DateValue) Parse(s string) error {
564564
func (d *DateTimeValue) Parse(s string) error {
565565
formats := []string{
566566
time.RFC3339,
567-
"2006-01-02T15:04:05Z07:00",
567+
time.RFC3339Nano,
568568
"2006-01-02T15:04:05",
569569
"2006-01-02 15:04:05",
570570
time.RFC1123,
@@ -584,6 +584,7 @@ func (d *DateTimeValue) Parse(s string) error {
584584
func (t *TimeValue) Parse(s string) error {
585585
formats := []string{
586586
"15:04:05",
587+
"15:04:05.999999999Z07:00",
587588
"3:04:05PM",
588589
"3:04 PM",
589590
"15:04",

pkg/cmd/build_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package cmd
4+
5+
import (
6+
"testing"
7+
8+
"github.com/stainless-api/stainless-api-cli/internal/mocktest"
9+
)
10+
11+
func TestBuildsCreate(t *testing.T) {
12+
t.Skip("Prism tests are disabled")
13+
mocktest.TestRunMockTestWithFlags(
14+
t,
15+
"builds", "create",
16+
"--project", "project",
17+
"--revision", "string",
18+
"--allow-empty",
19+
"--branch", "branch",
20+
"--commit-message", "commit_message",
21+
"--target-commit-messages", "{cli: cli, csharp: csharp, go: go, java: java, kotlin: kotlin, node: node, openapi: openapi, php: php, python: python, ruby: ruby, terraform: terraform, typescript: typescript}",
22+
"--target", "node",
23+
)
24+
}
25+
26+
func TestBuildsRetrieve(t *testing.T) {
27+
t.Skip("Prism tests are disabled")
28+
mocktest.TestRunMockTestWithFlags(
29+
t,
30+
"builds", "retrieve",
31+
"--build-id", "buildId",
32+
)
33+
}
34+
35+
func TestBuildsList(t *testing.T) {
36+
t.Skip("Prism tests are disabled")
37+
mocktest.TestRunMockTestWithFlags(
38+
t,
39+
"builds", "list",
40+
"--project", "project",
41+
"--branch", "branch",
42+
"--cursor", "cursor",
43+
"--limit", "1",
44+
"--revision", "string",
45+
)
46+
}
47+
48+
func TestBuildsCompare(t *testing.T) {
49+
t.Skip("Prism tests are disabled")
50+
mocktest.TestRunMockTestWithFlags(
51+
t,
52+
"builds", "compare",
53+
"--base", "{branch: branch, revision: string, commit_message: commit_message}",
54+
"--head", "{branch: branch, revision: string, commit_message: commit_message}",
55+
"--project", "project",
56+
"--target", "node",
57+
)
58+
}

pkg/cmd/builddiagnostic_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package cmd
4+
5+
import (
6+
"testing"
7+
8+
"github.com/stainless-api/stainless-api-cli/internal/mocktest"
9+
)
10+
11+
func TestBuildsDiagnosticsList(t *testing.T) {
12+
t.Skip("Prism tests are disabled")
13+
mocktest.TestRunMockTestWithFlags(
14+
t,
15+
"builds:diagnostics", "list",
16+
"--build-id", "buildId",
17+
"--cursor", "cursor",
18+
"--limit", "1",
19+
"--severity", "fatal",
20+
"--targets", "targets",
21+
)
22+
}

pkg/cmd/buildtargetoutput_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package cmd
4+
5+
import (
6+
"testing"
7+
8+
"github.com/stainless-api/stainless-api-cli/internal/mocktest"
9+
)
10+
11+
func TestBuildsTargetOutputsRetrieve(t *testing.T) {
12+
t.Skip("Prism tests are disabled")
13+
mocktest.TestRunMockTestWithFlags(
14+
t,
15+
"builds:target-outputs", "retrieve",
16+
"--build-id", "build_id",
17+
"--target", "node",
18+
"--type", "source",
19+
"--output", "url",
20+
)
21+
}

pkg/cmd/flagoptions.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const (
2424
EmptyBody BodyContentType = iota
2525
MultipartFormEncoded
2626
ApplicationJSON
27+
ApplicationOctetStream
2728
)
2829

2930
func flagOptions(
@@ -125,12 +126,23 @@ func flagOptions(
125126
return nil, err
126127
}
127128
options = append(options, option.WithRequestBody(writer.FormDataContentType(), buf))
129+
128130
case ApplicationJSON:
129131
bodyBytes, err := json.Marshal(bodyData)
130132
if err != nil {
131133
return nil, err
132134
}
133135
options = append(options, option.WithRequestBody("application/json", bodyBytes))
136+
137+
case ApplicationOctetStream:
138+
if bodyBytes, ok := bodyData.([]byte); ok {
139+
options = append(options, option.WithRequestBody("application/octet-stream", bodyBytes))
140+
} else if bodyStr, ok := bodyData.(string); ok {
141+
options = append(options, option.WithRequestBody("application/octet-stream", []byte(bodyStr)))
142+
} else {
143+
return nil, fmt.Errorf("Unsupported body for application/octet-stream: %v", bodyData)
144+
}
145+
134146
default:
135147
panic("Invalid body content type!")
136148
}

pkg/cmd/org_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package cmd
4+
5+
import (
6+
"testing"
7+
8+
"github.com/stainless-api/stainless-api-cli/internal/mocktest"
9+
)
10+
11+
func TestOrgsRetrieve(t *testing.T) {
12+
t.Skip("Prism tests are disabled")
13+
mocktest.TestRunMockTestWithFlags(
14+
t,
15+
"orgs", "retrieve",
16+
"--org", "org",
17+
)
18+
}
19+
20+
func TestOrgsList(t *testing.T) {
21+
t.Skip("Prism tests are disabled")
22+
mocktest.TestRunMockTestWithFlags(
23+
t,
24+
"orgs", "list",
25+
)
26+
}

pkg/cmd/project_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package cmd
4+
5+
import (
6+
"testing"
7+
8+
"github.com/stainless-api/stainless-api-cli/internal/mocktest"
9+
)
10+
11+
func TestProjectsCreate(t *testing.T) {
12+
t.Skip("Prism tests are disabled")
13+
mocktest.TestRunMockTestWithFlags(
14+
t,
15+
"projects", "create",
16+
"--display-name", "display_name",
17+
"--org", "org",
18+
"--revision", "{foo: {content: content}}",
19+
"--slug", "slug",
20+
"--target", "node",
21+
)
22+
}
23+
24+
func TestProjectsRetrieve(t *testing.T) {
25+
t.Skip("Prism tests are disabled")
26+
mocktest.TestRunMockTestWithFlags(
27+
t,
28+
"projects", "retrieve",
29+
"--project", "project",
30+
)
31+
}
32+
33+
func TestProjectsUpdate(t *testing.T) {
34+
t.Skip("Prism tests are disabled")
35+
mocktest.TestRunMockTestWithFlags(
36+
t,
37+
"projects", "update",
38+
"--project", "project",
39+
"--display-name", "display_name",
40+
)
41+
}
42+
43+
func TestProjectsList(t *testing.T) {
44+
t.Skip("Prism tests are disabled")
45+
mocktest.TestRunMockTestWithFlags(
46+
t,
47+
"projects", "list",
48+
"--cursor", "cursor",
49+
"--limit", "1",
50+
"--org", "org",
51+
)
52+
}

0 commit comments

Comments
 (0)