Skip to content

Commit

Permalink
test(cli-client): add tests for client, validator and tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
zhijie-yang committed Jun 13, 2024
1 parent dcedd24 commit edf6f07
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/cli-client/internals/cli/validator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cli_test

import (
"testing"

"github.com/canonical/oci-factory/cli-client/internals/cli"
)

func TestValidateAndFormatDateLegalInput(t *testing.T) {
inputs := []string{"2006-07-08", "2008-09-10", "2024-05-01"}

for _, datetime := range inputs {
_, err := cli.ValidateAndFormatDate(datetime)
if err != nil {
t.Fatalf("Failed parsing legal time format yyyy-mm-dd, %v", err)
}
}
}

func TestValidateAndFormatDateBadInput(t *testing.T) {
inputs := []string{"2001-02-29", "2024-05-32", "01-01-2023"}

for _, datetime := range inputs {
_, err := cli.ValidateAndFormatDate(datetime)
if err == nil {
t.Fatalf("Parsing illegal date input [%s] didn't raise error", datetime)
}
}
}
46 changes: 46 additions & 0 deletions src/cli-client/internals/client/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package client_test

import (
"bytes"
"io"
"net/http"
"net/http/httptest"
"os"
"testing"

"github.com/canonical/oci-factory/cli-client/internals/client"
"github.com/canonical/oci-factory/cli-client/internals/token"
)

func TestSendRequest(t *testing.T) {
mockPayload := []byte(`{"mock":"payload"}`)
expectedStatusCode := http.StatusOK

// Create a mock server
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Verify the request method, URL, and payload
if r.Method != http.MethodPost {
t.Errorf("unexpected request method, want POST, got %s", r.Method)
}
body, _ := io.ReadAll(r.Body)
if !bytes.Equal(body, mockPayload) {
t.Errorf("unexpected request payload, want %s, got %s", string(mockPayload), string(body))
}
// Set the response status code and body
w.WriteHeader(expectedStatusCode)
w.Write([]byte(`{"mock":"response"}`))
}))
defer mockServer.Close()

saveToken := os.Getenv(token.TokenVarName)
os.Setenv(token.TokenVarName, "ghp_AAAAAAAA")
// Call the SendRequest function
response := client.SendRequest(http.MethodPost, mockServer.URL, mockPayload, expectedStatusCode)
token.RestoreTokenEnv(saveToken)

// Verify the response
expectedResponse := []byte(`{"mock":"response"}`)
if !bytes.Equal(response, expectedResponse) {
t.Errorf("unexpected response, want %s, got %s", string(expectedResponse), string(response))
}
}
53 changes: 53 additions & 0 deletions src/cli-client/internals/client/wf_dispatcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,30 @@ package client_test

import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
"os"
"testing"

"github.com/canonical/oci-factory/cli-client/internals/client"
"github.com/canonical/oci-factory/cli-client/internals/token"
)

func testHeaderEntriesEqual(header1 map[string][]string, header2 map[string]string) bool {
for key, value := range header2 {
fmt.Println(key, header1[key])
fmt.Println(key, header2[key])
fmt.Println(key, header1[key][0])
if header1[key][0] != value {
return false
}
}
return true
}

func TestSetHeaderWithMap(t *testing.T) {
mockUrl := "https://mock.url"
mockJson := []byte(`{"mock":"json"}`)
Expand All @@ -27,3 +42,41 @@ func TestSetHeaderWithMap(t *testing.T) {
t.Fatalf("request 1 not equals to request 2\nrequest1: %+v\nrequest2: %+v", request1, request2)
}
}

func TestDispatchWorkflow(t *testing.T) {
mockJson := []byte(`{"mock":"json"}`)
saveToken := token.UpdateEnvToken("ghp_AAAAAAAA")
header := client.NewGithubAuthHeaderMap()

expectedPayload := client.NewPayload("image-name", "image-trigger")
expectedPayloadJSON, _ := json.Marshal(expectedPayload)

// Create a mock server
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Verify the request method, URL, and payload
if r.Method != http.MethodPost {
t.Fatalf("unexpected request method, want POST, got %s", r.Method)
}
// Verify the request header
// TODO received header is missing X-GitHub-Api-Version
if !testHeaderEntriesEqual(r.Header, header) {
t.Fatalf("unexpected request header, want %v, got %v", header, r.Header)
}
// header setting is tested above and transferring is tested in the http library
body, _ := io.ReadAll(r.Body)
if !bytes.Equal(body, expectedPayloadJSON) {
t.Fatalf("unexpected request payload, want %s, got %s", string(expectedPayloadJSON), string(body))
}
// Set the no content response status code and body
w.WriteHeader(http.StatusNoContent)
w.Write([]byte(``))
}))
defer mockServer.Close()

request, _ := http.NewRequest(http.MethodPost, mockServer.URL, bytes.NewBuffer(mockJson))
client.SetHeaderWithMap(request, header)

// Call the DispatchWorkflow function
client.DispatchWorkflowImpl_(expectedPayload, mockServer.URL)
token.RestoreTokenEnv(saveToken)
}
43 changes: 43 additions & 0 deletions src/cli-client/internals/client/wf_poller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package client_test

import (
"testing"

"github.com/canonical/oci-factory/cli-client/internals/client"
)

func TestGetWorkflowRunStatusFromResp(t *testing.T) {
mockResponseBody := []byte(`{"status":"completed","conclusion":"success"}`)
expectedStatus := "completed"
expectedConclusion := "success"

status, conclusion := client.GetWorkflowRunStatusFromResp(mockResponseBody)

// Verify the response
if status != expectedStatus {
t.Errorf("unexpected status, want %s, got %s", expectedStatus, status)
}
if conclusion != expectedConclusion {
t.Errorf("unexpected conclusion, want %s, got %s", expectedConclusion, conclusion)
}
}

func TestGetWorkflowJobsProgressFromResp(t *testing.T) {
mockResponseBody := []byte(`{"jobs":[{"name":"Job 1","status":"completed"},{"name":"Job 2","status":"in_progress"},{"name":"Job 3","status":"queued"}]}`)
expectedCurrJob := 2
expectedTotalJobs := 3
expectedJobName := "Job 2"

currJob, totalJobs, jobName := client.GetWorkflowJobsProgressFromResp(mockResponseBody)

// Verify the response
if currJob != expectedCurrJob {
t.Errorf("unexpected current job, want %d, got %d", expectedCurrJob, currJob)
}
if totalJobs != expectedTotalJobs {
t.Errorf("unexpected total jobs, want %d, got %d", expectedTotalJobs, totalJobs)
}
if jobName != expectedJobName {
t.Errorf("unexpected job name, want %s, got %s", expectedJobName, jobName)
}
}
16 changes: 16 additions & 0 deletions src/cli-client/internals/token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"golang.org/x/term"
)

const TokenVarName = "GITHUB_TOKEN"

var _accessToken = ""

func readAccessToken() string {
Expand All @@ -33,3 +35,17 @@ func GetAccessToken() string {
}
return _accessToken
}

func RestoreTokenEnv(saveToken string) {
if len(saveToken) == 0 {
os.Unsetenv(TokenVarName)
} else {
os.Setenv(TokenVarName, saveToken)
}
}

func UpdateEnvToken(token string) string {
saveToken := os.Getenv(TokenVarName)
os.Setenv(TokenVarName, token)
return saveToken
}
25 changes: 25 additions & 0 deletions src/cli-client/internals/token/token_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package token_test

import (
"os"
"testing"

"github.com/canonical/oci-factory/cli-client/internals/token"
)

func TestReadAccessTokenEnv(t *testing.T) {
expectedToken := "ghp_test123ToKeN"
saveToken := token.UpdateEnvToken(expectedToken)
err := os.Setenv(token.TokenVarName, expectedToken)
if err != nil {
t.Fatalf("Unable to set env variable: %v", err)
}
resultToken := token.GetAccessToken()
if resultToken != expectedToken {
t.Fatalf("")
}
token.RestoreTokenEnv(saveToken)
if os.Getenv(token.TokenVarName) != saveToken {
t.Fatalf("Unable to restore saved env variable")
}
}

0 comments on commit edf6f07

Please sign in to comment.