| @@ -1,59 +1,62 @@ | |||
| package main | |||
| import "log" | |||
| import "encoding/json" | |||
| import "strings" | |||
| //abstract CRUD operation for espoCRM Entity | |||
| var crmSite = "https://c.hitxy.org.au/" | |||
| func createEntity(entityType string, jsonB []byte) (entity interface{}, err error) { | |||
| url := crmSite + "api/v1/" + entityType | |||
| json, err := postRAW(jsonB, url, crmBuildCommonAPIHeader()) | |||
| jsonStr, err := postRAW(jsonB, url, crmBuildCommonAPIHeader()) | |||
| if err != nil { | |||
| log.Println(err) | |||
| return | |||
| } | |||
| return json, err | |||
| return json2Entity(entityType, jsonStr) | |||
| } | |||
| func updateEntity(entityType string, id string, jsonB []byte) (entity interface{}, err error) { | |||
| url := crmSite + "api/v1/" + entityType + "/" + id | |||
| json, err := patchRAW(jsonB, url, crmBuildCommonAPIHeader()) | |||
| jsonStr, err := patchRAW(jsonB, url, crmBuildCommonAPIHeader()) | |||
| if err != nil { | |||
| log.Println(err) | |||
| return | |||
| } | |||
| return json, err | |||
| return json2Entity(entityType, jsonStr) | |||
| } | |||
| func replaceEntity(entityType string, id string, jsonB []byte) (entity interface{}, err error) { | |||
| url := crmSite + "api/v1/" + entityType + "/" + id | |||
| json, err := putRAW(jsonB, url, crmBuildCommonAPIHeader()) | |||
| jsonStr, err := putRAW(jsonB, url, crmBuildCommonAPIHeader()) | |||
| if err != nil { | |||
| log.Println(err) | |||
| return | |||
| } | |||
| return json, err | |||
| return json2Entity(entityType, jsonStr) | |||
| } | |||
| func deleteEntity(entityType string, id string) (json string, err error) { | |||
| func deleteEntity(entityType string, id string) (deleted bool, err error) { | |||
| url := crmSite + "api/v1/" + entityType + "/" + id | |||
| json, err = deleteRAW(url, crmBuildCommonAPIHeader()) | |||
| resp, err := deleteRAW(url, crmBuildCommonAPIHeader()) | |||
| if err != nil { | |||
| log.Println(err) | |||
| return | |||
| } | |||
| deleted = strings.ToLower(resp) == "true" | |||
| return | |||
| } | |||
| //give an id, return json | |||
| func crmGetEntity(entityType string, id string) (json string, err error) { | |||
| func crmGetEntity(entityType string, id string) (entity interface{}, err error) { | |||
| url := crmSite + "api/v1/" + entityType + "/" + id | |||
| json, err = getRAW(url, crmBuildCommonAPIHeader()) | |||
| jsonStr, err := getRAW(url, crmBuildCommonAPIHeader()) | |||
| if err != nil { | |||
| log.Println(err) | |||
| return | |||
| } | |||
| return json, err | |||
| return json2Entity(entityType, jsonStr) | |||
| } | |||
| func crmBuildCommonAPIHeader() (headers map[string]string) { | |||
| @@ -65,11 +68,20 @@ func crmBuildCommonAPIHeader() (headers map[string]string) { | |||
| } | |||
| //given a json string, convert it to Typed structure | |||
| func json2Entity(entityType string, json string) (r interface{}) { | |||
| func json2Entity(entityType string, data string) (r interface{}, err error) { | |||
| switch entityType { | |||
| case "Lead": | |||
| r = crmdLeadInfo | |||
| e := crmdLead{} | |||
| err = json.Unmarshal([]byte(data), &e) | |||
| r = e | |||
| case "Account": | |||
| //r = crmdAccount{} | |||
| default: | |||
| log.Fatalf("json2Entity: Unknown EntityType %s", entityType) | |||
| } | |||
| if err != nil { | |||
| log.Println(err) | |||
| } | |||
| return | |||
| } | |||
| @@ -1,9 +1,74 @@ | |||
| package main | |||
| import "testing" | |||
| import ( | |||
| "encoding/json" | |||
| "log" | |||
| "testing" | |||
| "time" | |||
| ) | |||
| func TestGetEntity(t *testing.T) { | |||
| SetupConfig() | |||
| leadID := "595071f8450974b72" | |||
| crmGetEntity("Lead", leadID) | |||
| entity, err := crmGetEntity("Lead", leadID) | |||
| AssertEqual(t, err, nil, "get entity should return nil error") | |||
| lead, ok := entity.(crmdLead) | |||
| AssertEqual(t, ok, true, "type assertion should be true") | |||
| AssertEqual(t, leadID, lead.ID, "lead id mismatch") | |||
| lead1 := entity.(crmdLead) | |||
| AssertEqual(t, lead.ID, lead1.ID, "type casting should work") | |||
| } | |||
| func TestCreateEntity(t *testing.T) { | |||
| SetupConfig() | |||
| e := crmdLead{} | |||
| e.FirstName = "ff" + time.Now().Format("2006-jan-02 03:04:05") | |||
| e.LastName = "ll" | |||
| e.Password = "pp" | |||
| e.Status = "New" | |||
| b, _ := json.Marshal(e) | |||
| log.Println(string(b)) | |||
| entity, _ := createEntity("Lead", b) | |||
| lead1 := entity.(crmdLead) | |||
| log.Println(lead1) | |||
| lead2, _ := crmGetLead(lead1.ID) | |||
| AssertEqual(t, lead2.ID, lead1.ID, "lead id should be equal") | |||
| e.Password = "newpass" | |||
| b, _ = json.Marshal(e) | |||
| entity, _ = updateEntity("Lead", lead2.ID, b) | |||
| lead3 := entity.(crmdLead) | |||
| log.Println(lead3) | |||
| AssertEqual(t, lead3.ID, lead1.ID, "should be same lead") | |||
| AssertEqual(t, lead3.Password, "newpass", "password should have been changed") | |||
| AssertEqual(t, lead1.Password, "pp", "old password should be PP") | |||
| //delete this test lead. | |||
| deleted, _ := deleteEntity("Lead", lead1.ID) | |||
| AssertEqual(t, deleted, true, "record should be deleted") | |||
| } | |||
| func TestCreateDuplicate(t *testing.T) { | |||
| SetupConfig() | |||
| e := crmdLead{} | |||
| e.FirstName = "ff" + time.Now().Format("2006-jan-02 03:04:05") | |||
| e.LastName = "ll" | |||
| e.Password = "pp" | |||
| e.Status = "New" | |||
| e.WechatHitxyID = "someopenid" | |||
| b, _ := json.Marshal(e) | |||
| entity, _ := createEntity("Lead", b) | |||
| lead1 := entity.(crmdLead) | |||
| entity, _ = crmGetEntity("Lead", lead1.ID) | |||
| lead2 := entity.(crmdLead) | |||
| AssertEqual(t, lead1.ID, lead2.ID, "lead should have been created successfully") | |||
| //try to create it again | |||
| entity, err := createEntity("Lead", b) | |||
| ehttp := err.(errorHTTPResponse) | |||
| AssertEqual(t, err == nil, false, "should have error for duplicates") | |||
| } | |||
| @@ -0,0 +1,46 @@ | |||
| { | |||
| "reason": "Duplicate", | |||
| "data": { | |||
| "59547585c158b7cab": { | |||
| "id": "59547585c158b7cab", | |||
| "name": "ff2017-jan-29 01:35:33 ll", | |||
| "deleted": false, | |||
| "salutationName": null, | |||
| "firstName": "ff2017-jan-29 01:35:33", | |||
| "lastName": "ll", | |||
| "title": null, | |||
| "status": "New", | |||
| "source": "", | |||
| "industry": "", | |||
| "opportunityAmount": null, | |||
| "website": null, | |||
| "addressStreet": null, | |||
| "addressCity": null, | |||
| "addressState": null, | |||
| "addressCountry": null, | |||
| "addressPostalCode": null, | |||
| "emailAddress": null, | |||
| "phoneNumber": null, | |||
| "doNotCall": false, | |||
| "description": null, | |||
| "createdAt": "2017-06-29 03:35:33", | |||
| "modifiedAt": "2017-06-29 03:35:33", | |||
| "accountName": null, | |||
| "password": "pp", | |||
| "wechat_hitxy_id": "someopenid", | |||
| "verifier": null, | |||
| "opportunityAmountCurrency": null, | |||
| "opportunityAmountConverted": null, | |||
| "createdById": "58ef420cac3cf6c95", | |||
| "createdByName": "wechat robot", | |||
| "modifiedById": null, | |||
| "modifiedByName": null, | |||
| "assignedUserId": null, | |||
| "assignedUserName": null, | |||
| "campaignId": null, | |||
| "createdAccountId": null, | |||
| "createdContactId": null, | |||
| "createdOpportunityId": null | |||
| } | |||
| } | |||
| } | |||