Skip to content

Commit

Permalink
Merge pull request #4 from fullcontact/fix-multifield-querying
Browse files Browse the repository at this point in the history
Fix multifield querying
  • Loading branch information
vyasswaroop authored Mar 12, 2021
2 parents fc32bc6 + 2278f7d commit 8c07b71
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 92 deletions.
2 changes: 1 addition & 1 deletion fc/constants.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package fullcontact

const (
version = "1.1.0"
version = "1.1.1"
userAgent = "FullContact_Go_Client_V" + version
FcApiKey = "FC_API_KEY"
FCGoClientTestType = "FCGoClientTestType"
Expand Down
9 changes: 7 additions & 2 deletions fc/fullcontact.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,18 @@ func sendToChannel(ch chan *APIResponse, response *http.Response, url string, er
Request is converted to JSON and sends a Asynchronous request */
func (fcClient *fullContactClient) PersonEnrich(personRequest *PersonRequest) chan *APIResponse {
ch := make(chan *APIResponse)

if personRequest == nil {
go sendToChannel(ch, nil, "", NewFullContactError("Person Request can't be nil"))
return ch
}
reqBytes, err := json.Marshal(personRequest)
err := validatePersonRequest(personRequest)
if err != nil {
go sendToChannel(ch, nil, "", err)
return ch
}

reqBytes, err := json.Marshal(personRequest)
if err != nil {
go sendToChannel(ch, nil, "", err)
return ch
Expand Down Expand Up @@ -277,7 +283,6 @@ func (fcClient *fullContactClient) IdentityDelete(resolveRequest *ResolveRequest

func (fcClient *fullContactClient) resolveRequest(ch chan *APIResponse, resolveRequest *ResolveRequest, url string) chan *APIResponse {
reqBytes, err := json.Marshal(resolveRequest)

if err != nil {
go sendToChannel(ch, nil, "", err)
return ch
Expand Down
57 changes: 33 additions & 24 deletions fc/person_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,21 @@ type PersonRequest struct {

func NewPersonRequest(option ...PersonRequestOption) (*PersonRequest, error) {
pr := &PersonRequest{}

for _, opt := range option {
opt(pr)
}
err := validatePersonRequest(pr)
if err != nil {
pr = nil
}
return pr, err
return pr, nil
}

func (pr *PersonRequest) isQueryable() bool {
return pr.Emails != nil ||
pr.Phones != nil ||
pr.Profiles != nil ||
pr.Maid != nil ||
isPopulated(pr.RecordId) ||
isPopulated(pr.PersonId) ||
isPopulated(pr.PartnerId) ||
isPopulated(pr.LiNonId)
}

func validatePersonRequest(pr *PersonRequest) error {
Expand All @@ -40,28 +46,31 @@ func validatePersonRequest(pr *PersonRequest) error {
pr.Confidence != "MAX" {
return NewFullContactError("Confidence value can only be 'LOW', 'MED', 'HIGH', 'MAX'")
}
if pr.Location == nil && pr.Name == nil {
return nil
} else if pr.Location != nil && pr.Name != nil {
// Validating Location fields
if isPopulated(pr.Location.AddressLine1) &&
((isPopulated(pr.Location.City) &&
(isPopulated(pr.Location.Region) || isPopulated(pr.Location.RegionCode))) ||
(isPopulated(pr.Location.PostalCode))) {
// Validating Name fields
if (isPopulated(pr.Name.Full)) ||
(isPopulated(pr.Name.Given) && isPopulated(pr.Name.Family)) {
return nil
if !pr.isQueryable() {
if pr.Location == nil && pr.Name == nil {
return nil
} else if pr.Location != nil && pr.Name != nil {
// Validating Location fields
if isPopulated(pr.Location.AddressLine1) &&
((isPopulated(pr.Location.City) &&
(isPopulated(pr.Location.Region) || isPopulated(pr.Location.RegionCode))) ||
(isPopulated(pr.Location.PostalCode))) {
// Validating Name fields
if (isPopulated(pr.Name.Full)) ||
(isPopulated(pr.Name.Given) && isPopulated(pr.Name.Family)) {
return nil
} else {
return NewFullContactError("Name data requires full name or given and family name")
}
} else {
return NewFullContactError("Name data requires full name or given and family name")
return NewFullContactError(
"Location data requires addressLine1 and postalCode or addressLine1, city and regionCode (or region)")
}
} else {
return NewFullContactError(
"Location data requires addressLine1 and postalCode or addressLine1, city and regionCode (or region)")
}
return NewFullContactError(
"If you want to use 'location' or 'name' as an input, both must be present and they must have non-blank values")
}
return NewFullContactError(
"If you want to use 'location' or 'name' as an input, both must be present and they must have non-blank values")
return nil
}

func WithEmail(email string) PersonRequestOption {
Expand Down
112 changes: 94 additions & 18 deletions fc/person_request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,31 @@ func TestMarshallNewPersonRequest(t *testing.T) {
}

func TestNewPersonRequestWithoutNameAndLocation(t *testing.T) {
_, err := NewPersonRequest(WithEmail("marianrd97@outlook.com"))
pr, _ := NewPersonRequest(WithEmail("marianrd97@outlook.com"))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestNewPersonRequestWithNameOnly(t *testing.T) {
_, err := NewPersonRequest(WithEmail("marianrd97@outlook.com"),
func TestNewPersonRequestWithNameOnlyWithQueryable(t *testing.T) {
pr, _ := NewPersonRequest(WithEmail("marianrd97@outlook.com"),
WithName(&PersonName{
Full: "Marian C Reed",
}))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestNewPersonRequestWithNameOnlyWithoutQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithName(&PersonName{
Full: "Marian C Reed",
}))
err := validatePersonRequest(pr)
assert.EqualError(t, err, "FullContactError: If you want to use 'location' or 'name' as an input, both must be present and they must have non-blank values")
}

func TestNewPersonRequestWithLocationOnly(t *testing.T) {
_, err := NewPersonRequest(
func TestNewPersonRequestWithLocationOnlyWithQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithEmail("marianrd97@outlook.com"),
WithLocation(NewLocation(
WithAddressLine1("123/23"),
Expand All @@ -65,11 +76,25 @@ func TestNewPersonRequestWithLocationOnly(t *testing.T) {
WithRegionForLocation("Denver"),
WithRegionCode("123123"),
WithPostalCode("23124"))))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestNewPersonRequestWithLocationOnlyWithoutQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithLocation(NewLocation(
WithAddressLine1("123/23"),
WithAddressLine2("Some Street"),
WithCity("Denver"),
WithRegionForLocation("Denver"),
WithRegionCode("123123"),
WithPostalCode("23124"))))
err := validatePersonRequest(pr)
assert.EqualError(t, err, "FullContactError: If you want to use 'location' or 'name' as an input, both must be present and they must have non-blank values")
}

func TestNewPersonRequestWithLocationWithoutAddressLine1(t *testing.T) {
_, err := NewPersonRequest(
func TestNewPersonRequestWithLocationWithoutAddressLine1WithQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithEmail("marianrd97@outlook.com"),
WithName(NewPersonName(WithFull("Test Name"))),
WithLocation(NewLocation(
Expand All @@ -78,79 +103,130 @@ func TestNewPersonRequestWithLocationWithoutAddressLine1(t *testing.T) {
WithRegionForLocation("Denver"),
WithRegionCode("123123"),
WithPostalCode("23124"))))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestNewPersonRequestWithLocationWithoutAddressLine1WithoutQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithName(NewPersonName(WithFull("Test Name"))),
WithLocation(NewLocation(
WithAddressLine2("Some Street"),
WithCity("Denver"),
WithRegionForLocation("Denver"),
WithRegionCode("123123"),
WithPostalCode("23124"))))
err := validatePersonRequest(pr)
assert.EqualError(t, err, "FullContactError: Location data requires addressLine1 and postalCode or addressLine1, city and regionCode (or region)")
}

func TestNewPersonRequestWithLocationOnlyAddressLine1(t *testing.T) {
_, err := NewPersonRequest(
func TestNewPersonRequestWithLocationOnlyAddressLine1WithQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithEmail("marianrd97@outlook.com"),
WithName(NewPersonName(WithFull("Test Name"))),
WithLocation(NewLocation(
WithAddressLine1("123/23"))))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestNewPersonRequestWithLocationOnlyAddressLine1WithoutQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithName(NewPersonName(WithFull("Test Name"))),
WithLocation(NewLocation(
WithAddressLine1("123/23"))))
err := validatePersonRequest(pr)
assert.EqualError(t, err, "FullContactError: Location data requires addressLine1 and postalCode or addressLine1, city and regionCode (or region)")
}

func TestNewPersonRequestWithLocationWithAddressLine1AndCity(t *testing.T) {
_, err := NewPersonRequest(
func TestNewPersonRequestWithLocationWithAddressLine1AndCityWithQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithEmail("marianrd97@outlook.com"),
WithName(NewPersonName(WithFull("Test Name"))),
WithLocation(NewLocation(
WithAddressLine1("123/23"),
WithCity("Denver"))))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestNewPersonRequestWithLocationWithAddressLine1AndCityWithoutQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithName(NewPersonName(WithFull("Test Name"))),
WithLocation(NewLocation(
WithAddressLine1("123/23"),
WithCity("Denver"))))
err := validatePersonRequest(pr)
assert.EqualError(t, err, "FullContactError: Location data requires addressLine1 and postalCode or addressLine1, city and regionCode (or region)")
}

func TestNewPersonRequestWithLocationWithAddressLine1AndRegion(t *testing.T) {
_, err := NewPersonRequest(
func TestNewPersonRequestWithLocationWithAddressLine1AndRegionWithQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithEmail("marianrd97@outlook.com"),
WithName(NewPersonName(WithFull("Test Name"))),
WithLocation(NewLocation(
WithAddressLine1("123/23"),
WithRegionCode("123123"))))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestNewPersonRequestWithLocationWithAddressLine1AndRegionWithoutQueryable(t *testing.T) {
pr, _ := NewPersonRequest(
WithName(NewPersonName(WithFull("Test Name"))),
WithLocation(NewLocation(
WithAddressLine1("123/23"),
WithRegionCode("123123"))))
err := validatePersonRequest(pr)
assert.EqualError(t, err, "FullContactError: Location data requires addressLine1 and postalCode or addressLine1, city and regionCode (or region)")
}

func TestNewPersonRequestWithValidLocation1(t *testing.T) {
_, err := NewPersonRequest(
pr, _ := NewPersonRequest(
WithName(&PersonName{Full: "Marian C Reed"}),
WithLocation(NewLocation(
WithAddressLine1("123/23"),
WithPostalCode("12343"))))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestNewPersonRequestWithValidLocation2(t *testing.T) {
_, err := NewPersonRequest(
pr, _ := NewPersonRequest(
WithName(&PersonName{Full: "Marian C Reed"}),
WithLocation(NewLocation(
WithAddressLine1("123/23"),
WithCity("Denver"),
WithRegionCode("123123"))))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestNewPersonRequestWithValidLocation3(t *testing.T) {
_, err := NewPersonRequest(
pr, _ := NewPersonRequest(
WithName(&PersonName{Full: "Marian C Reed"}),
WithLocation(NewLocation(
WithAddressLine1("123/23"),
WithAddressLine2("Some Street"),
WithCity("Denver"),
WithRegionForLocation("123123"))))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestNewPersonRequestWithValidName(t *testing.T) {
_, err := NewPersonRequest(
pr, _ := NewPersonRequest(
WithName(&PersonName{Given: "Marian", Family: "Reed"}),
WithLocation(NewLocation(
WithAddressLine1("123/23"),
WithPostalCode("23432"))))
err := validatePersonRequest(pr)
assert.NoError(t, err)
}

func TestWithConfidence(t *testing.T) {
_, err := NewPersonRequest(WithConfidence("test"))
pr, _ := NewPersonRequest(WithConfidence("test"))
err := validatePersonRequest(pr)
assert.EqualError(t, err, "FullContactError: Confidence value can only be 'LOW', 'MED', 'HIGH', 'MAX'")
}

Expand Down
Loading

0 comments on commit 8c07b71

Please sign in to comment.