Skip to content

Commit

Permalink
Merge pull request #23 from k-capehart/issue7-increase-test-coverage
Browse files Browse the repository at this point in the history
issue7 increase test coverage
  • Loading branch information
k-capehart authored May 2, 2024
2 parents 8a3005d + 2296ea5 commit ec91d53
Show file tree
Hide file tree
Showing 13 changed files with 2,126 additions and 208 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cover.out
cover.html
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ go get github.com/k-capehart/go-salesforce
### Types
```go
type Salesforce struct {
auth *authorization
auth *authentication
}

type Creds struct {
Expand Down Expand Up @@ -825,4 +825,16 @@ if err != nil {
panic(err)
}
fmt.Println(string(respBody))
```
```

## Contributing
Anyone is welcome to contribute. Open an issue or discussion post first to track the effort.

- Fork this repository
- When testing code locally, place this line in your module's `go.mod`
- `replace github.com/k-capehart/go-salesforce => /path_to_local_fork/`
- Run tests
- `go test -cover`
- Generate code coverage output
- `go test -v -coverprofile cover.out`
- `go tool cover -html cover.out -o cover.html`
8 changes: 4 additions & 4 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"strings"
)

type authorization struct {
type authentication struct {
AccessToken string `json:"access_token"`
InstanceUrl string `json:"instance_url"`
Id string `json:"id"`
Expand All @@ -27,13 +27,13 @@ type Creds struct {
}

func validateAuth(sf Salesforce) error {
if sf.auth == nil {
if sf.auth == nil || sf.auth.AccessToken == "" {
return errors.New("not authenticated: please use salesforce.Init()")
}
return nil
}

func loginPassword(domain string, username string, password string, securityToken string, consumerKey string, consumerSecret string) (*authorization, error) {
func loginPassword(domain string, username string, password string, securityToken string, consumerKey string, consumerSecret string) (*authentication, error) {
payload := url.Values{
"grant_type": {"password"},
"client_id": {consumerKey},
Expand All @@ -56,7 +56,7 @@ func loginPassword(domain string, username string, password string, securityToke
return nil, err
}

auth := &authorization{}
auth := &authentication{}
jsonError := json.Unmarshal(respBody, &auth)
if jsonError != nil {
return nil, jsonError
Expand Down
14 changes: 6 additions & 8 deletions auth_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package salesforce

import (
"encoding/json"
"net/http"
"net/http/httptest"
"reflect"
Expand All @@ -20,7 +19,9 @@ func Test_validateAuth(t *testing.T) {
{
name: "validation_success",
args: args{
sf: Salesforce{auth: &authorization{}},
sf: Salesforce{auth: &authentication{
AccessToken: "1234",
}},
},
wantErr: false,
},
Expand All @@ -42,17 +43,14 @@ func Test_validateAuth(t *testing.T) {
}

func Test_loginPassword(t *testing.T) {
auth := authorization{
auth := authentication{
AccessToken: "1234",
InstanceUrl: "example.com",
Id: "123abc",
IssuedAt: "01/01/1970",
Signature: "signed",
}
body, _ := json.Marshal(auth)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write(body)
}))
server, _ := setupTestServer(auth, http.StatusOK)
defer server.Close()

badserver := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -71,7 +69,7 @@ func Test_loginPassword(t *testing.T) {
tests := []struct {
name string
args args
want *authorization
want *authentication
wantErr bool
}{
{
Expand Down
75 changes: 37 additions & 38 deletions bulk.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const (
queryJobType = "query"
)

func updateJobState(job bulkJob, state string, auth authorization) error {
func updateJobState(job bulkJob, state string, auth authentication) error {
job.State = state
body, _ := json.Marshal(job)
resp, err := doRequest(http.MethodPatch, "/jobs/ingest/"+job.Id, jsonType, auth, string(body))
Expand All @@ -72,7 +72,7 @@ func updateJobState(job bulkJob, state string, auth authorization) error {
return nil
}

func createBulkJob(auth authorization, jobType string, body []byte) (bulkJob, error) {
func createBulkJob(auth authentication, jobType string, body []byte) (bulkJob, error) {
resp, err := doRequest(http.MethodPost, "/jobs/"+jobType, jsonType, auth, string(body))
if err != nil {
return bulkJob{}, err
Expand All @@ -95,7 +95,7 @@ func createBulkJob(auth authorization, jobType string, body []byte) (bulkJob, er
return *newJob, nil
}

func uploadJobData(auth authorization, data string, bulkJob bulkJob) error {
func uploadJobData(auth authentication, data string, bulkJob bulkJob) error {
resp, uploadDataErr := doRequest("PUT", "/jobs/ingest/"+bulkJob.Id+"/batches", csvType, auth, data)
if uploadDataErr != nil {
updateJobState(bulkJob, jobStateAborted, auth)
Expand All @@ -113,7 +113,7 @@ func uploadJobData(auth authorization, data string, bulkJob bulkJob) error {
return nil
}

func getJobResults(auth authorization, jobType string, bulkJobId string) (BulkJobResults, error) {
func getJobResults(auth authentication, jobType string, bulkJobId string) (BulkJobResults, error) {
resp, err := doRequest(http.MethodGet, "/jobs/"+jobType+"/"+bulkJobId, jsonType, auth, "")
if err != nil {
return BulkJobResults{}, err
Expand All @@ -136,9 +136,9 @@ func getJobResults(auth authorization, jobType string, bulkJobId string) (BulkJo
return *bulkJobResults, nil
}

func waitForJobResult(auth authorization, bulkJobId string, c chan error) {
err := wait.PollUntilContextTimeout(context.Background(), time.Second, time.Minute, false, func(context.Context) (bool, error) {
bulkJob, reqErr := getJobResults(auth, ingestJobType, bulkJobId)
func waitForJobResultsAsync(auth authentication, bulkJobId string, jobType string, interval time.Duration, c chan error) {
err := wait.PollUntilContextTimeout(context.Background(), interval, time.Minute, false, func(context.Context) (bool, error) {
bulkJob, reqErr := getJobResults(auth, jobType, bulkJobId)
if reqErr != nil {
return true, reqErr
}
Expand All @@ -147,7 +147,18 @@ func waitForJobResult(auth authorization, bulkJobId string, c chan error) {
c <- err
}

func isBulkJobDone(auth authorization, bulkJob BulkJobResults) (bool, error) {
func waitForJobResults(auth authentication, bulkJobId string, jobType string, interval time.Duration) error {
err := wait.PollUntilContextTimeout(context.Background(), interval, time.Minute, false, func(context.Context) (bool, error) {
bulkJob, reqErr := getJobResults(auth, jobType, bulkJobId)
if reqErr != nil {
return true, reqErr
}
return isBulkJobDone(auth, bulkJob)
})
return err
}

func isBulkJobDone(auth authentication, bulkJob BulkJobResults) (bool, error) {
if bulkJob.State == jobStateJobComplete || bulkJob.State == jobStateFailed {
if bulkJob.ErrorMessage != "" {
return true, errors.New(bulkJob.ErrorMessage)
Expand All @@ -167,7 +178,7 @@ func isBulkJobDone(auth authorization, bulkJob BulkJobResults) (bool, error) {
return false, nil
}

func getQueryJobResults(auth authorization, bulkJobId string, locator string) (bulkJobQueryResults, error) {
func getQueryJobResults(auth authentication, bulkJobId string, locator string) (bulkJobQueryResults, error) {
uri := "/jobs/query/" + bulkJobId + "/results"
if locator != "" {
uri = uri + "/?locator=" + locator
Expand Down Expand Up @@ -200,18 +211,7 @@ func getQueryJobResults(auth authorization, bulkJobId string, locator string) (b
return queryResults, nil
}

func waitForQueryResults(auth authorization, bulkJobId string) ([][]string, error) {
err := wait.PollUntilContextTimeout(context.Background(), time.Second, time.Minute, false, func(context.Context) (bool, error) {
bulkJob, reqErr := getJobResults(auth, queryJobType, bulkJobId)
if reqErr != nil {
return true, reqErr
}
return isBulkJobDone(auth, bulkJob)
})
if err != nil {
return nil, err
}

func collectQueryResults(auth authentication, bulkJobId string) ([][]string, error) {
queryResults, resultsErr := getQueryJobResults(auth, bulkJobId, "")
if resultsErr != nil {
return nil, resultsErr
Expand All @@ -224,11 +224,10 @@ func waitForQueryResults(auth authorization, bulkJobId string) ([][]string, erro
}
records = append(records, queryResults.Data[1:]...) // don't include headers in subsequent batches
}

return records, nil
}

func getFailedRecords(auth authorization, bulkJobId string) (string, error) {
func getFailedRecords(auth authentication, bulkJobId string) (string, error) {
resp, err := doRequest(http.MethodGet, "/jobs/ingest/"+bulkJobId+"/failedResults", jsonType, auth, "")
if err != nil {
return "", err
Expand Down Expand Up @@ -338,7 +337,7 @@ func writeCSVFile(filePath string, data [][]string) error {
return nil
}

func constructBulkJobRequest(auth authorization, sObjectName string, operation string, fieldName string) (bulkJob, error) {
func constructBulkJobRequest(auth authentication, sObjectName string, operation string, fieldName string) (bulkJob, error) {
jobReq := bulkJobCreationRequest{
Object: sObjectName,
Operation: operation,
Expand All @@ -361,7 +360,7 @@ func constructBulkJobRequest(auth authorization, sObjectName string, operation s
return job, nil
}

func doBulkJob(auth authorization, sObjectName string, fieldName string, operation string, records any, batchSize int, waitForResults bool) ([]string, error) {
func doBulkJob(auth authentication, sObjectName string, fieldName string, operation string, records any, batchSize int, waitForResults bool) ([]string, error) {
recordMap, err := convertToSliceOfMaps(records)
if err != nil {
return []string{}, err
Expand All @@ -377,6 +376,7 @@ func doBulkJob(auth authorization, sObjectName string, fieldName string, operati
} else {
batch = recordMap
}
recordMap = remaining

job, constructJobErr := constructBulkJobRequest(auth, sObjectName, operation, fieldName)
if constructJobErr != nil {
Expand All @@ -393,18 +393,14 @@ func doBulkJob(auth authorization, sObjectName string, fieldName string, operati

uploadErr := uploadJobData(auth, data, job)
if uploadErr != nil {
fmt.Println("tesst")
jobErrors = uploadErr
break
}

recordMap = remaining
}

if waitForResults {
for _, id := range jobIds {
c := make(chan error)
go waitForJobResult(auth, id, c)
go waitForJobResultsAsync(auth, id, ingestJobType, time.Second, c)
jobError := <-c
if jobError != nil {
jobErrors = errors.Join(jobErrors, jobError)
Expand All @@ -415,7 +411,7 @@ func doBulkJob(auth authorization, sObjectName string, fieldName string, operati
return jobIds, jobErrors
}

func doBulkJobWithFile(auth authorization, sObjectName string, fieldName string, operation string, filePath string, batchSize int, waitForResults bool) ([]string, error) {
func doBulkJobWithFile(auth authentication, sObjectName string, fieldName string, operation string, filePath string, batchSize int, waitForResults bool) ([]string, error) {
var jobErrors error
var jobIds []string

Expand All @@ -434,6 +430,7 @@ func doBulkJobWithFile(auth authorization, sObjectName string, fieldName string,
} else {
batch = records
}
records = remaining

job, constructJobErr := constructBulkJobRequest(auth, sObjectName, operation, fieldName)
if constructJobErr != nil {
Expand All @@ -457,14 +454,12 @@ func doBulkJobWithFile(auth authorization, sObjectName string, fieldName string,
if uploadErr != nil {
jobErrors = errors.Join(jobErrors, uploadErr)
}

records = remaining
}

if waitForResults {
for _, id := range jobIds {
c := make(chan error)
go waitForJobResult(auth, id, c)
go waitForJobResultsAsync(auth, id, ingestJobType, time.Second, c)
jobError := <-c
if jobError != nil {
jobErrors = errors.Join(jobErrors, jobError)
Expand All @@ -475,7 +470,7 @@ func doBulkJobWithFile(auth authorization, sObjectName string, fieldName string,
return jobIds, jobErrors
}

func doQueryBulk(auth authorization, filePath string, query string) error {
func doQueryBulk(auth authentication, filePath string, query string) error {
queryJobReq := bulkQueryJobCreationRequest{
Operation: queryJobType,
Query: query,
Expand All @@ -494,9 +489,13 @@ func doQueryBulk(auth authorization, filePath string, query string) error {
return newErr
}

records, jobErr := waitForQueryResults(auth, job.Id)
if jobErr != nil {
return jobErr
pollErr := waitForJobResults(auth, job.Id, queryJobType, time.Second)
if pollErr != nil {
return pollErr
}
records, reqErr := collectQueryResults(auth, job.Id)
if reqErr != nil {
return reqErr
}
writeErr := writeCSVFile(filePath, records)
if writeErr != nil {
Expand Down
Loading

0 comments on commit ec91d53

Please sign in to comment.