Skip to content

Commit

Permalink
Merge pull request rapidpro#619 from nyaruka/preview_start_endpoint
Browse files Browse the repository at this point in the history
Add endpoint to generate a flow start preview
  • Loading branch information
rowanseymour authored Apr 20, 2022
2 parents c4bc1e7 + 57a1381 commit 3314713
Show file tree
Hide file tree
Showing 12 changed files with 439 additions and 322 deletions.
52 changes: 7 additions & 45 deletions core/models/groups_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/nyaruka/mailroom/testsuite/testdata"

"github.com/lib/pq"
"github.com/olivere/elastic/v7"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -60,7 +59,7 @@ func TestLoadGroups(t *testing.T) {
}
}

func TestDynamicGroups(t *testing.T) {
func TestSmartGroups(t *testing.T) {
ctx, rt, db, _ := testsuite.Get()

defer testsuite.Reset(testsuite.ResetAll)
Expand All @@ -82,68 +81,32 @@ func TestDynamicGroups(t *testing.T) {
oa, err := models.GetOrgAssetsWithRefresh(ctx, rt, testdata.Org1.ID, models.RefreshCampaigns|models.RefreshGroups)
assert.NoError(t, err)

esServer := testsuite.NewMockElasticServer()
defer esServer.Close()
mockES := testsuite.NewMockElasticServer()
defer mockES.Close()

es, err := elastic.NewClient(
elastic.SetURL(esServer.URL()),
elastic.SetHealthcheck(false),
elastic.SetSniff(false),
)
assert.NoError(t, err)

contactHit := `{
"_scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAbgc0WS1hqbHlfb01SM2lLTWJRMnVOSVZDdw==",
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "contacts",
"_type": "_doc",
"_id": "%d",
"_score": null,
"_routing": "1",
"sort": [
15124352
]
}
]
}
}`
es := mockES.Client()

cathyHit := fmt.Sprintf(contactHit, testdata.Cathy.ID)
bobHit := fmt.Sprintf(contactHit, testdata.Bob.ID)
mockES.AddResponse(testdata.Cathy.ID)
mockES.AddResponse(testdata.Bob.ID)
mockES.AddResponse(testdata.Bob.ID)

tcs := []struct {
Query string
ESResponse string
ContactIDs []models.ContactID
EventContactIDs []models.ContactID
}{
{
"cathy",
cathyHit,
[]models.ContactID{testdata.Cathy.ID},
[]models.ContactID{},
},
{
"bob",
bobHit,
[]models.ContactID{testdata.Bob.ID},
[]models.ContactID{testdata.Bob.ID},
},
{
"unchanged",
bobHit,
[]models.ContactID{testdata.Bob.ID},
[]models.ContactID{testdata.Bob.ID},
},
Expand All @@ -153,7 +116,6 @@ func TestDynamicGroups(t *testing.T) {
err := models.UpdateGroupStatus(ctx, db, testdata.DoctorsGroup.ID, models.GroupStatusInitializing)
assert.NoError(t, err)

esServer.NextResponse = tc.ESResponse
count, err := models.PopulateDynamicGroup(ctx, db, es, oa, testdata.DoctorsGroup.ID, tc.Query)
assert.NoError(t, err, "error populating dynamic group for: %s", tc.Query)

Expand Down
2 changes: 1 addition & 1 deletion core/models/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func GetContactIDsForQueryPage(ctx context.Context, client *elastic.Client, oa *
return nil, nil, 0, err
}

logrus.WithFields(logrus.Fields{"org_id": oa.OrgID(), "query": query, "elapsed": time.Since(start), "page_count": len(ids), "total_count": results.Hits.TotalHits}).Debug("paged contact query complete")
logrus.WithFields(logrus.Fields{"org_id": oa.OrgID(), "query": query, "elapsed": time.Since(start), "page_count": len(ids), "total_count": results.Hits.TotalHits.Value}).Debug("paged contact query complete")

return parsed, ids, results.Hits.TotalHits.Value, nil
}
Expand Down
159 changes: 18 additions & 141 deletions core/models/search_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package models_test

import (
"fmt"
"testing"

"github.com/nyaruka/goflow/test"
Expand All @@ -17,15 +16,13 @@ import (
func TestGetContactIDsForQueryPage(t *testing.T) {
ctx, rt, _, _ := testsuite.Get()

es := testsuite.NewMockElasticServer()
defer es.Close()
mockES := testsuite.NewMockElasticServer()
defer mockES.Close()

client, err := elastic.NewClient(
elastic.SetURL(es.URL()),
elastic.SetHealthcheck(false),
elastic.SetSniff(false),
)
require.NoError(t, err)
mockES.AddResponse(testdata.George.ID)
mockES.AddResponse(testdata.George.ID)

es := mockES.Client()

oa, err := models.GetOrgAssets(ctx, rt, testdata.Org1.ID)
require.NoError(t, err)
Expand All @@ -36,7 +33,6 @@ func TestGetContactIDsForQueryPage(t *testing.T) {
Query string
Sort string
ExpectedESRequest string
MockedESResponse string
ExpectedContacts []models.ContactID
ExpectedTotal int64
ExpectedError string
Expand Down Expand Up @@ -85,33 +81,6 @@ func TestGetContactIDsForQueryPage(t *testing.T) {
],
"track_total_hits": true
}`,
MockedESResponse: fmt.Sprintf(`{
"_scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAbgc0WS1hqbHlfb01SM2lLTWJRMnVOSVZDdw==",
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "contacts",
"_type": "_doc",
"_id": "%d",
"_score": null,
"_routing": "1",
"sort": [
15124352
]
}
]
}
}`, testdata.George.ID),
ExpectedContacts: []models.ContactID{testdata.George.ID},
ExpectedTotal: 1,
},
Expand Down Expand Up @@ -197,33 +166,6 @@ func TestGetContactIDsForQueryPage(t *testing.T) {
],
"track_total_hits": true
}`,
MockedESResponse: fmt.Sprintf(`{
"_scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAbgc0WS1hqbHlfb01SM2lLTWJRMnVOSVZDdw==",
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "contacts",
"_type": "_doc",
"_id": "%d",
"_score": null,
"_routing": "1",
"sort": [
15124352
]
}
]
}
}`, testdata.George.ID),
ExpectedContacts: []models.ContactID{testdata.George.ID},
ExpectedTotal: 1,
},
Expand All @@ -235,11 +177,9 @@ func TestGetContactIDsForQueryPage(t *testing.T) {
}

for i, tc := range tcs {
es.NextResponse = tc.MockedESResponse

group := oa.GroupByID(tc.Group.ID)

_, ids, total, err := models.GetContactIDsForQueryPage(ctx, client, oa, group, tc.ExcludeIDs, tc.Query, tc.Sort, 0, 50)
_, ids, total, err := models.GetContactIDsForQueryPage(ctx, es, oa, group, tc.ExcludeIDs, tc.Query, tc.Sort, 0, 50)

if tc.ExpectedError != "" {
assert.EqualError(t, err, tc.ExpectedError)
Expand All @@ -248,22 +188,22 @@ func TestGetContactIDsForQueryPage(t *testing.T) {
assert.Equal(t, tc.ExpectedContacts, ids, "%d: ids mismatch", i)
assert.Equal(t, tc.ExpectedTotal, total, "%d: total mismatch", i)

test.AssertEqualJSON(t, []byte(tc.ExpectedESRequest), []byte(es.LastRequestBody), "%d: ES request mismatch", i)
test.AssertEqualJSON(t, []byte(tc.ExpectedESRequest), []byte(mockES.LastRequestBody), "%d: ES request mismatch", i)
}
}
}

func TestGetContactIDsForQuery(t *testing.T) {
ctx, rt, _, _ := testsuite.Get()

es := testsuite.NewMockElasticServer()
defer es.Close()
mockES := testsuite.NewMockElasticServer()
defer mockES.Close()

client, err := elastic.NewClient(
elastic.SetURL(es.URL()),
elastic.SetHealthcheck(false),
elastic.SetSniff(false),
)
mockES.AddResponse(testdata.George.ID)
mockES.AddResponse()
mockES.AddResponse(testdata.George.ID)

es, err := elastic.NewClient(elastic.SetURL(mockES.URL()), elastic.SetHealthcheck(false), elastic.SetSniff(false))
require.NoError(t, err)

oa, err := models.GetOrgAssets(ctx, rt, 1)
Expand Down Expand Up @@ -314,33 +254,6 @@ func TestGetContactIDsForQuery(t *testing.T) {
},
"sort":["_doc"]
}`,
mockedESResponse: fmt.Sprintf(`{
"_scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAbgc0WS1hqbHlfb01SM2lLTWJRMnVOSVZDdw==",
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "contacts",
"_type": "_doc",
"_id": "%d",
"_score": null,
"_routing": "1",
"sort": [
15124352
]
}
]
}
}`, testdata.George.ID),
expectedContacts: []models.ContactID{testdata.George.ID},
}, {
query: "nobody",
Expand Down Expand Up @@ -378,22 +291,6 @@ func TestGetContactIDsForQuery(t *testing.T) {
},
"sort":["_doc"]
}`,
mockedESResponse: `{
"_scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAbgc0WS1hqbHlfb01SM2lLTWJRMnVOSVZDdw==",
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}`,
expectedContacts: []models.ContactID{},
},
{
Expand Down Expand Up @@ -433,24 +330,6 @@ func TestGetContactIDsForQuery(t *testing.T) {
},
"size": 1
}`,
mockedESResponse: fmt.Sprintf(`{
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "contacts",
"_type": "_doc",
"_id": "%d",
"_score": null,
"_routing": "1",
"sort": [
15124352
]
}
]
}
}`, testdata.George.ID),
expectedContacts: []models.ContactID{testdata.George.ID},
},
{
Expand All @@ -461,18 +340,16 @@ func TestGetContactIDsForQuery(t *testing.T) {
}

for i, tc := range tcs {
es.NextResponse = tc.mockedESResponse

ids, err := models.GetContactIDsForQuery(ctx, client, oa, tc.query, tc.limit)
ids, err := models.GetContactIDsForQuery(ctx, es, oa, tc.query, tc.limit)

if tc.expectedError != "" {
assert.EqualError(t, err, tc.expectedError)
} else {
assert.NoError(t, err, "%d: error encountered performing query", i)
assert.Equal(t, tc.expectedContacts, ids, "%d: ids mismatch", i)

assert.Equal(t, tc.expectedRequestURL, es.LastRequestURL, "%d: request URL mismatch", i)
test.AssertEqualJSON(t, []byte(tc.expectedRequestBody), []byte(es.LastRequestBody), "%d: request body mismatch", i)
assert.Equal(t, tc.expectedRequestURL, mockES.LastRequestURL, "%d: request URL mismatch", i)
test.AssertEqualJSON(t, []byte(tc.expectedRequestBody), []byte(mockES.LastRequestBody), "%d: request body mismatch", i)
}
}
}
Loading

0 comments on commit 3314713

Please sign in to comment.