Skip to content
91 changes: 91 additions & 0 deletions integration-tests/certificate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package tests

import (
"net/http/httptest"
"testing"
"time"

"github.com/stretchr/testify/assert"

"github.com/upsun/cli/pkg/mockapi"
)

func TestCertificateList(t *testing.T) {
authServer := mockapi.NewAuthServer(t)
defer authServer.Close()

apiHandler := mockapi.NewHandler(t)
apiServer := httptest.NewServer(apiHandler)
defer apiServer.Close()

projectID := mockapi.ProjectID()
apiHandler.SetProjects([]*mockapi.Project{{
ID: projectID,
Links: mockapi.MakeHALLinks(
"self=/projects/"+projectID,
"environments=/projects/"+projectID+"/environments",
),
DefaultBranch: "main",
}})

main := makeEnv(projectID, "main", "production", "active", nil)
apiHandler.SetEnvironments([]*mockapi.Environment{main})

created, _ := time.Parse(time.RFC3339, "2024-01-01T00:00:00Z")
expires, _ := time.Parse(time.RFC3339, "2027-01-01T00:00:00Z")
apiHandler.SetProjectCertificates(projectID, []*mockapi.Certificate{
{
ID: "cert1",
Domains: []string{"example.com", "www.example.com"},
Issuer: "Custom CA",
IsProvisioned: false,
ExpiresAt: expires,
CreatedAt: created,
UpdatedAt: created,
Links: mockapi.MakeHALLinks(
"self=/projects/" + projectID + "/certificates/cert1",
),
},
})

f := newCommandFactory(t, apiServer.URL, authServer.URL)
f.Run("cc")

// List certificates.
output := f.Run("certificates", "-p", projectID)
assert.Contains(t, output, "cert1")
assert.Contains(t, output, "example.com")

// Get a specific certificate property.
assertTrimmed(t, "Custom CA", f.Run("certificate:get", "-p", projectID, "cert1", "-P", "issuer"))
}

func TestCertificateListEmpty(t *testing.T) {
authServer := mockapi.NewAuthServer(t)
defer authServer.Close()

apiHandler := mockapi.NewHandler(t)
apiServer := httptest.NewServer(apiHandler)
defer apiServer.Close()

projectID := mockapi.ProjectID()
apiHandler.SetProjects([]*mockapi.Project{{
ID: projectID,
Links: mockapi.MakeHALLinks(
"self=/projects/"+projectID,
"environments=/projects/"+projectID+"/environments",
),
DefaultBranch: "main",
}})

main := makeEnv(projectID, "main", "production", "active", nil)
apiHandler.SetEnvironments([]*mockapi.Environment{main})

f := newCommandFactory(t, apiServer.URL, authServer.URL)
f.Run("cc")

// Empty certificate list.
_, stdErr, err := f.RunCombinedOutput("certificates", "-p", projectID)
assert.NoError(t, err)
assert.Contains(t, stdErr, "No certificates found")
}
28 changes: 28 additions & 0 deletions integration-tests/decode_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package tests

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestDecode(t *testing.T) {
f := &cmdFactory{t: t}

// Simple base64-encoded JSON.
assertTrimmed(t, `{
"foo": "bar"
}`, f.Run("decode", "eyJmb28iOiAiYmFyIn0="))

// Property extraction.
assertTrimmed(t, "bar", f.Run("decode", "eyJmb28iOiAiYmFyIn0=", "-P", "foo"))

// Nested property extraction.
input := "eyJhIjogeyJiIjogImMifX0=" // {"a": {"b": "c"}}
assertTrimmed(t, "c", f.Run("decode", input, "-P", "a.b"))

// Invalid base64 input.
_, stdErr, err := f.RunCombinedOutput("decode", "not-valid-base64!")
assert.Error(t, err)
assert.Contains(t, stdErr, "Invalid value")
}
108 changes: 108 additions & 0 deletions integration-tests/domain_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package tests

import (
"net/http/httptest"
"testing"
"time"

"github.com/stretchr/testify/assert"

"github.com/upsun/cli/pkg/mockapi"
)

func TestDomainList(t *testing.T) {
authServer := mockapi.NewAuthServer(t)
defer authServer.Close()

apiHandler := mockapi.NewHandler(t)
apiServer := httptest.NewServer(apiHandler)
defer apiServer.Close()

projectID := mockapi.ProjectID()
apiHandler.SetProjects([]*mockapi.Project{{
ID: projectID,
Links: mockapi.MakeHALLinks(
"self=/projects/"+projectID,
"environments=/projects/"+projectID+"/environments",
"domains=/projects/"+projectID+"/domains",
),
DefaultBranch: "main",
}})

main := makeEnv(projectID, "main", "production", "active", nil)
apiHandler.SetEnvironments([]*mockapi.Environment{main})

created, _ := time.Parse(time.RFC3339, "2024-01-15T10:00:00Z")
apiHandler.SetProjectDomains(projectID, []*mockapi.Domain{
{
ID: "example.com",
Name: "example.com",
Type: "production",
IsDefault: true,
SSL: &mockapi.DomainSSL{HasCertificate: true},
CreatedAt: created,
UpdatedAt: created,
Links: mockapi.MakeHALLinks(
"self=/projects/"+projectID+"/domains/example.com",
"#edit=/projects/"+projectID+"/domains/example.com",
),
},
{
ID: "www.example.com",
Name: "www.example.com",
Type: "production",
IsDefault: false,
SSL: &mockapi.DomainSSL{HasCertificate: true},
CreatedAt: created,
UpdatedAt: created,
Links: mockapi.MakeHALLinks(
"self=/projects/"+projectID+"/domains/www.example.com",
"#edit=/projects/"+projectID+"/domains/www.example.com",
),
},
})

f := newCommandFactory(t, apiServer.URL, authServer.URL)
f.Run("cc")

// List domains.
output := f.Run("domains", "-p", projectID)
assert.Contains(t, output, "example.com")
assert.Contains(t, output, "www.example.com")

// Get a specific domain property.
assertTrimmed(t, "production", f.Run("domain:get", "-p", projectID, "example.com", "-P", "type"))
}

func TestDomainListEmpty(t *testing.T) {
authServer := mockapi.NewAuthServer(t)
defer authServer.Close()

apiHandler := mockapi.NewHandler(t)
apiServer := httptest.NewServer(apiHandler)
defer apiServer.Close()

projectID := mockapi.ProjectID()
apiHandler.SetProjects([]*mockapi.Project{{
ID: projectID,
Links: mockapi.MakeHALLinks(
"self=/projects/"+projectID,
"environments=/projects/"+projectID+"/environments",
"domains=/projects/"+projectID+"/domains",
),
DefaultBranch: "main",
}})

main := makeEnv(projectID, "main", "production", "active", nil)
apiHandler.SetEnvironments([]*mockapi.Environment{main})

f := newCommandFactory(t, apiServer.URL, authServer.URL)
f.Run("cc")

// Empty domain list outputs a message to stderr.
// Note: the CLI currently exits non-zero for this, which is arguably a bug
// (cf. services/certificates which exit 0 for empty lists). Not asserting
// the exit code so this test won't break if that gets fixed.
_, stdErr, _ := f.RunCombinedOutput("domains", "-p", projectID)
assert.Contains(t, stdErr, "No domains found")
}
47 changes: 47 additions & 0 deletions integration-tests/environment_activate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package tests

import (
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"

"github.com/upsun/cli/pkg/mockapi"
)

func TestEnvironmentActivate(t *testing.T) {
authServer := mockapi.NewAuthServer(t)
defer authServer.Close()

apiHandler := mockapi.NewHandler(t)
apiServer := httptest.NewServer(apiHandler)
defer apiServer.Close()

projectID := mockapi.ProjectID()
apiHandler.SetProjects([]*mockapi.Project{{
ID: projectID,
Links: mockapi.MakeHALLinks(
"self=/projects/"+projectID,
"environments=/projects/"+projectID+"/environments",
),
DefaultBranch: "main",
}})

main := makeEnv(projectID, "main", "production", "active", nil)
inactive := makeEnv(projectID, "staging", "staging", "inactive", "main")
inactive.Links["#activate"] = mockapi.HALLink{HREF: "/projects/" + projectID + "/environments/staging/activate"}
apiHandler.SetEnvironments([]*mockapi.Environment{main, inactive})

f := newCommandFactory(t, apiServer.URL, authServer.URL)
f.Run("cc")

// Activate an inactive environment.
_, stdErr, err := f.RunCombinedOutput("environment:activate", "-p", projectID, "-e", "staging", "--no-wait")
assert.NoError(t, err)
assert.Contains(t, stdErr, "Activating environment")

// Activating an already-active environment (no #activate link) reports it.
_, stdErr, err = f.RunCombinedOutput("environment:activate", "-p", projectID, "-e", "main")
assert.NoError(t, err)
assert.Contains(t, stdErr, "already active")
}
75 changes: 75 additions & 0 deletions integration-tests/environment_pause_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package tests

import (
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"

"github.com/upsun/cli/pkg/mockapi"
)

func TestEnvironmentPause(t *testing.T) {
authServer := mockapi.NewAuthServer(t)
defer authServer.Close()

apiHandler := mockapi.NewHandler(t)
apiServer := httptest.NewServer(apiHandler)
defer apiServer.Close()

projectID := mockapi.ProjectID()
apiHandler.SetProjects([]*mockapi.Project{{
ID: projectID,
Links: mockapi.MakeHALLinks(
"self=/projects/"+projectID,
"environments=/projects/"+projectID+"/environments",
),
DefaultBranch: "main",
}})

main := makeEnv(projectID, "main", "production", "active", nil)
main.Links["#pause"] = mockapi.HALLink{HREF: "/projects/" + projectID + "/environments/main/pause"}
apiHandler.SetEnvironments([]*mockapi.Environment{main})

f := newCommandFactory(t, apiServer.URL, authServer.URL)
f.Run("cc")

// Pause an active environment.
stdOut, stdErr, err := f.RunCombinedOutput("environment:pause", "-p", projectID, "-e", ".", "--no-wait")
assert.NoError(t, err)
// The CLI outputs confirmation and pause messages on stderr.
combined := stdOut + stdErr
assert.Contains(t, combined, "pause")
}

func TestEnvironmentResume(t *testing.T) {
authServer := mockapi.NewAuthServer(t)
defer authServer.Close()

apiHandler := mockapi.NewHandler(t)
apiServer := httptest.NewServer(apiHandler)
defer apiServer.Close()

projectID := mockapi.ProjectID()
apiHandler.SetProjects([]*mockapi.Project{{
ID: projectID,
Links: mockapi.MakeHALLinks(
"self=/projects/"+projectID,
"environments=/projects/"+projectID+"/environments",
),
DefaultBranch: "main",
}})

main := makeEnv(projectID, "main", "production", "paused", nil)
main.Links["#resume"] = mockapi.HALLink{HREF: "/projects/" + projectID + "/environments/main/resume"}
apiHandler.SetEnvironments([]*mockapi.Environment{main})

f := newCommandFactory(t, apiServer.URL, authServer.URL)
f.Run("cc")

// Resume a paused environment.
stdOut, stdErr, err := f.RunCombinedOutput("environment:resume", "-p", projectID, "-e", ".", "--no-wait")
assert.NoError(t, err)
combined := stdOut + stdErr
assert.Contains(t, combined, "resum")
}
Loading
Loading