Skip to content
This repository has been archived by the owner on Mar 11, 2021. It is now read-only.

Commit

Permalink
Adds WIT parameter in TrackerQuery payload (#2360)
Browse files Browse the repository at this point in the history
  • Loading branch information
DhritiShikhar authored Dec 21, 2018
1 parent 5c95c04 commit ac1460f
Show file tree
Hide file tree
Showing 15 changed files with 330 additions and 159 deletions.
13 changes: 8 additions & 5 deletions controller/trackerquery.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,15 @@ func (c *TrackerqueryController) Create(ctx *app.CreateTrackerqueryContext) erro
}
err = application.Transactional(c.db, func(appl application.Application) error {
trackerQuery := remoteworkitem.TrackerQuery{
Query: ctx.Payload.Data.Attributes.Query,
Schedule: ctx.Payload.Data.Attributes.Schedule,
TrackerID: ctx.Payload.Data.Relationships.Tracker.Data.ID,
SpaceID: *ctx.Payload.Data.Relationships.Space.Data.ID,
Query: ctx.Payload.Data.Attributes.Query,
Schedule: ctx.Payload.Data.Attributes.Schedule,
TrackerID: ctx.Payload.Data.Relationships.Tracker.Data.ID,
SpaceID: *ctx.Payload.Data.Relationships.Space.Data.ID,
WorkItemTypeID: ctx.Payload.Data.Relationships.WorkItemType.Data.ID,
}
if ctx.Payload.Data.ID != nil {
trackerQuery.ID = *ctx.Payload.Data.ID
}
trackerQuery.ID = *ctx.Payload.Data.ID
tq, err := appl.TrackerQueries().Create(ctx.Context, trackerQuery)
if err != nil {
return errs.Wrapf(err, "failed to create tracker query %s", ctx.Payload.Data)
Expand Down
152 changes: 91 additions & 61 deletions controller/trackerquery_blackbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package controller_test
import (
"bytes"
"net/http"
"strconv"
"testing"

jwt "github.com/dgrijalva/jwt-go"
Expand Down Expand Up @@ -35,20 +36,20 @@ func TestRunTrackerQueryREST(t *testing.T) {
suite.Run(t, &TestTrackerQueryREST{DBTestSuite: gormtestsupport.NewDBTestSuite()})
}

func (rest *TestTrackerQueryREST) SetupTest() {
rest.DBTestSuite.SetupTest()
rest.RwiScheduler = remoteworkitem.NewScheduler(rest.DB)
rest.db = gormapplication.NewGormDB(rest.DB)
func (s *TestTrackerQueryREST) SetupTest() {
s.DBTestSuite.SetupTest()
s.RwiScheduler = remoteworkitem.NewScheduler(s.DB)
s.db = gormapplication.NewGormDB(s.DB)
}

func (rest *TestTrackerQueryREST) SecuredController() (*goa.Service, *TrackerController, *TrackerqueryController) {
func (s *TestTrackerQueryREST) SecuredController() (*goa.Service, *TrackerController, *TrackerqueryController) {
svc := testsupport.ServiceAsUser("TrackerQuery-Service", testsupport.TestIdentity)
return svc, NewTrackerController(svc, rest.db, rest.RwiScheduler, rest.Configuration), NewTrackerqueryController(svc, rest.db, rest.RwiScheduler, rest.Configuration)
return svc, NewTrackerController(svc, s.db, s.RwiScheduler, s.Configuration), NewTrackerqueryController(svc, s.db, s.RwiScheduler, s.Configuration)
}

func (rest *TestTrackerQueryREST) UnSecuredController() (*goa.Service, *TrackerController, *TrackerqueryController) {
func (s *TestTrackerQueryREST) UnSecuredController() (*goa.Service, *TrackerController, *TrackerqueryController) {
svc := goa.New("TrackerQuery-Service")
return svc, NewTrackerController(svc, rest.db, rest.RwiScheduler, rest.Configuration), NewTrackerqueryController(svc, rest.db, rest.RwiScheduler, rest.Configuration)
return svc, NewTrackerController(svc, s.db, s.RwiScheduler, s.Configuration), NewTrackerqueryController(svc, s.db, s.RwiScheduler, s.Configuration)
}

func getTrackerQueryTestData(t *testing.T) []testSecureAPI {
Expand Down Expand Up @@ -133,95 +134,122 @@ func getTrackerQueryTestData(t *testing.T) []testSecureAPI {
}

// This test case will check authorized access to Create/Update/Delete APIs
func (rest *TestTrackerQueryREST) TestUnauthorizeTrackerQueryCUD() {
UnauthorizeCreateUpdateDeleteTest(rest.T(), getTrackerQueryTestData, func() *goa.Service {
func (s *TestTrackerQueryREST) TestUnauthorizeTrackerQueryCUD() {
UnauthorizeCreateUpdateDeleteTest(s.T(), getTrackerQueryTestData, func() *goa.Service {
return goa.New("TestUnauthorizedTrackerQuery-Service")
}, func(service *goa.Service) error {
controller := NewTrackerqueryController(service, rest.GormDB, rest.RwiScheduler, rest.Configuration)
controller := NewTrackerqueryController(service, s.GormDB, s.RwiScheduler, s.Configuration)
app.MountTrackerqueryController(service, controller)
return nil
})
}

func (rest *TestTrackerQueryREST) TestCreateTrackerQuery() {
t := rest.T()
resource.Require(t, resource.Database)
func (s *TestTrackerQueryREST) TestCreateTrackerQuery() {
resource.Require(s.T(), resource.Database)

svc, _, trackerQueryCtrl := rest.SecuredController()
fxt := tf.NewTestFixture(t, rest.DB, tf.Spaces(1), tf.Trackers(1))
assert.NotNil(t, fxt.Spaces[0], fxt.Trackers[0])
svc, _, trackerQueryCtrl := s.SecuredController()
fxt := tf.NewTestFixture(s.T(), s.DB, tf.Spaces(1), tf.Trackers(1), tf.WorkItemTypes(1))
assert.NotNil(s.T(), fxt.Spaces[0], fxt.Trackers[0])

tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID)
s.T().Run("create tq - success", func(t *testing.T) {
tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID, fxt.WorkItemTypes[0].ID)
_, tqresult := test.CreateTrackerqueryCreated(t, svc.Context, svc, trackerQueryCtrl, &tqpayload)
assert.NotNil(t, tqresult)
})

_, tqresult := test.CreateTrackerqueryCreated(t, svc.Context, svc, trackerQueryCtrl, &tqpayload)
assert.NotNil(t, tqresult)
}
s.T().Run("nil WIT in trackerquery payload", func(t *testing.T) {
fxt := tf.NewTestFixture(t, s.DB,
tf.Spaces(1),
tf.Trackers(1),
)
svc, _, trackerQueryCtrl := s.SecuredController()

tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID, uuid.Nil)
_, err := test.CreateTrackerqueryBadRequest(t, svc.Context, svc, trackerQueryCtrl, &tqpayload)
require.NotNil(t, err)
require.IsType(t, strconv.Itoa(http.StatusBadRequest), *err.Errors[0].Status)
})

func (rest *TestTrackerQueryREST) TestShowTrackerQuery() {
t := rest.T()
resource.Require(t, resource.Database)
s.T().Run("disallow creation if WIT belongs to different spacetemplate", func(t *testing.T) {
fxt := tf.NewTestFixture(t, s.DB,
tf.SpaceTemplates(2),
tf.Spaces(1),
tf.WorkItemTypes(1, func(fxt *tf.TestFixture, idx int) error {
fxt.WorkItemTypes[idx].SpaceTemplateID = fxt.SpaceTemplates[1].ID
return nil
}),
tf.Trackers(1),
)
svc, _, trackerQueryCtrl := s.SecuredController()

svc, _, trackerQueryCtrl := rest.SecuredController()
fxt := tf.NewTestFixture(t, rest.DB, tf.Spaces(1), tf.Trackers(1))
assert.NotNil(t, fxt.Spaces[0], fxt.Trackers[0])
tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID, fxt.WorkItemTypes[0].ID)
_, err := test.CreateTrackerqueryBadRequest(t, svc.Context, svc, trackerQueryCtrl, &tqpayload)
require.NotNil(t, err)
require.IsType(t, strconv.Itoa(http.StatusBadRequest), *err.Errors[0].Status)
})
}

tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID)
func (s *TestTrackerQueryREST) TestShowTrackerQuery() {
resource.Require(s.T(), resource.Database)

_, tqresult := test.CreateTrackerqueryCreated(t, svc.Context, svc, trackerQueryCtrl, &tqpayload)
svc, _, trackerQueryCtrl := s.SecuredController()
fxt := tf.NewTestFixture(s.T(), s.DB, tf.Spaces(1), tf.Trackers(1), tf.WorkItemTypes(1))
assert.NotNil(s.T(), fxt.Spaces[0], fxt.Trackers[0])

_, tqr := test.ShowTrackerqueryOK(t, svc.Context, svc, trackerQueryCtrl, *tqresult.Data.ID)
assert.NotNil(t, tqr)
assert.Equal(t, tqresult.Data.ID, tqr.Data.ID)
tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID, fxt.WorkItemTypes[0].ID)

_, tqresult := test.CreateTrackerqueryCreated(s.T(), svc.Context, svc, trackerQueryCtrl, &tqpayload)
_, tqr := test.ShowTrackerqueryOK(s.T(), svc.Context, svc, trackerQueryCtrl, *tqresult.Data.ID)
assert.NotNil(s.T(), tqr)
assert.Equal(s.T(), tqresult.Data.ID, tqr.Data.ID)
}

// This test ensures that List does not return NIL items.
func (rest *TestTrackerQueryREST) TestTrackerQueryListItemsNotNil() {
t := rest.T()
resource.Require(t, resource.Database)
func (s *TestTrackerQueryREST) TestTrackerQueryListItemsNotNil() {
resource.Require(s.T(), resource.Database)

svc, _, trackerQueryCtrl := rest.SecuredController()
fxt := tf.NewTestFixture(t, rest.DB, tf.Spaces(1), tf.Trackers(1))
assert.NotNil(t, fxt.Spaces[0], fxt.Trackers[0])
svc, _, trackerQueryCtrl := s.SecuredController()
fxt := tf.NewTestFixture(s.T(), s.DB, tf.Spaces(1), tf.Trackers(1), tf.WorkItemTypes(1))
assert.NotNil(s.T(), fxt.Spaces[0], fxt.Trackers[0])

tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID)
_, tq1 := test.CreateTrackerqueryCreated(t, svc.Context, svc, trackerQueryCtrl, &tqpayload)
assert.NotNil(t, tq1)
tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID, fxt.WorkItemTypes[0].ID)
_, tq1 := test.CreateTrackerqueryCreated(s.T(), svc.Context, svc, trackerQueryCtrl, &tqpayload)
assert.NotNil(s.T(), tq1)

tqpayload2 := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID)
_, tq2 := test.CreateTrackerqueryCreated(t, svc.Context, svc, trackerQueryCtrl, &tqpayload2)
assert.NotNil(t, tq2)
tqpayload2 := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID, fxt.WorkItemTypes[0].ID)
_, tq2 := test.CreateTrackerqueryCreated(s.T(), svc.Context, svc, trackerQueryCtrl, &tqpayload2)
assert.NotNil(s.T(), tq2)

_, list := test.ListTrackerqueryOK(t, svc.Context, svc, trackerQueryCtrl, nil, nil)
assert.NotNil(t, list.Data)
_, list := test.ListTrackerqueryOK(s.T(), svc.Context, svc, trackerQueryCtrl, nil, nil)
assert.NotNil(s.T(), list.Data)
}

// This test ensures that ID returned by Show is valid.
// refer : https://github.com/fabric8-services/fabric8-wit/issues/189
func (rest *TestTrackerQueryREST) TestCreateTrackerQueryID() {
t := rest.T()
resource.Require(t, resource.Database)
func (s *TestTrackerQueryREST) TestCreateTrackerQueryID() {
resource.Require(s.T(), resource.Database)

svc, _, trackerQueryCtrl := rest.SecuredController()
fxt := tf.NewTestFixture(t, rest.DB, tf.Spaces(1), tf.Trackers(1))
svc, _, trackerQueryCtrl := s.SecuredController()
fxt := tf.NewTestFixture(s.T(), s.DB, tf.Spaces(1), tf.Trackers(1), tf.WorkItemTypes(1))

rest.T().Run("valid - success", func(t *testing.T) {
tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID)
s.T().Run("valid - success", func(t *testing.T) {
tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID, fxt.WorkItemTypes[0].ID)
_, trackerquery := test.CreateTrackerqueryCreated(t, svc.Context, svc, trackerQueryCtrl, &tqpayload)
require.NotNil(t, trackerquery)

_, result := test.ShowTrackerqueryOK(t, svc.Context, svc, trackerQueryCtrl, *trackerquery.Data.ID)
require.NotNil(t, result)
assert.Equal(t, trackerquery.Data.ID, result.Data.ID)
})
rest.T().Run("invalid - fail", func(t *testing.T) {
tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID)
s.T().Run("invalid - fail", func(t *testing.T) {
tqpayload := newCreateTrackerQueryPayload(fxt.Spaces[0].ID, fxt.Trackers[0].ID, fxt.WorkItemTypes[0].ID)
invalidID := uuid.Nil
tqpayload.Data.ID = &invalidID
test.CreateTrackerqueryBadRequest(t, svc.Context, svc, trackerQueryCtrl, &tqpayload)
})
}

func newCreateTrackerQueryPayload(spaceID uuid.UUID, trackerID uuid.UUID) app.CreateTrackerqueryPayload {
func newCreateTrackerQueryPayload(spaceID uuid.UUID, trackerID uuid.UUID, witID uuid.UUID) app.CreateTrackerqueryPayload {
trackerQueryID := uuid.NewV4()
return app.CreateTrackerqueryPayload{
Data: &app.TrackerQuery{
Expand All @@ -231,17 +259,19 @@ func newCreateTrackerQueryPayload(spaceID uuid.UUID, trackerID uuid.UUID) app.Cr
Schedule: "15 * * * * *",
},
Relationships: &app.TrackerQueryRelations{
Space: &app.RelationSpaces{
Data: &app.RelationSpacesData{
ID: &spaceID,
},
},
Space: app.NewSpaceRelation(spaceID, ""),
Tracker: &app.RelationKindUUID{
Data: &app.DataKindUUID{
ID: trackerID,
Type: remoteworkitem.APIStringTypeTrackers,
},
},
WorkItemType: &app.RelationBaseType{
Data: &app.BaseTypeData{
ID: witID,
Type: APIStringTypeWorkItemType,
},
},
},
Type: remoteworkitem.APIStringTypeTrackerQuery,
},
Expand Down
1 change: 1 addition & 0 deletions design/tracker_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var trackerQueryAttributes = a.Type("TrackerQueryAttributes", func() {
var trackerQueryRelationships = a.Type("TrackerQueryRelations", func() {
a.Attribute("tracker", relationKindUUID, "This defines the related tracker")
a.Attribute("space", relationSpaces, "This defines the owning space")
a.Attribute("workItemType", relationBaseType, "Defines what work item type to use when instantiating work items using this tracker query.")
})

var trackerQueryList = JSONList(
Expand Down
2 changes: 2 additions & 0 deletions migration/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,8 @@ func GetMigrations() Migrations {
// Version 110
m = append(m, steps{ExecuteSQLFile("110-trackerquery-to-use-uuid.sql")})

// Version 111
m = append(m, steps{ExecuteSQLFile("111-add-wit-to-trackerquery.sql")})
// Version N
//
// In order to add an upgrade, simply append an array of MigrationFunc to the
Expand Down
10 changes: 9 additions & 1 deletion migration/migration_blackbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func TestMigrations(t *testing.T) {
t.Run("TestMigration108", testMigration108NumberColumnForArea)
t.Run("TestMigration109", testMigration109NumberColumnForIteration)
t.Run("TestMigration110", testMigration110TrackerQueryID)

t.Run("TestMigration111", testMigration111WITinTrackerQuery)
// Perform the migration
err = migration.Migrate(sqlDB, databaseName)
require.NoError(t, err, "failed to execute database migration")
Expand Down Expand Up @@ -1401,6 +1401,14 @@ func testMigration110TrackerQueryID(t *testing.T) {
}
require.True(t, checkTqConstraint(t, "tracker_queries", "PRIMARY KEY"))
}
func testMigration111WITinTrackerQuery(t *testing.T) {
migrateToVersion(t, sqlDB, migrations[:112], 111)
require.True(t, dialect.HasColumn("tracker_queries", "work_item_type_id"))

// check foreign key to work_item_types(id) exists
require.True(t, dialect.HasForeignKey("tracker_queries", "tracker_queries_work_item_type_id_fkey"))

}

// runSQLscript loads the given filename from the packaged SQL test files and
// executes it on the given database. Golang text/template module is used
Expand Down
2 changes: 2 additions & 0 deletions migration/sql-files/111-add-wit-to-trackerquery.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DELETE FROM tracker_queries; -- tracker_queries was not fully supported and not in working condition before this
ALTER TABLE tracker_queries ADD COLUMN work_item_type_id uuid not null REFERENCES work_item_types(id) ON DELETE CASCADE;
2 changes: 1 addition & 1 deletion remoteworkitem/remoteworkitem.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ var RemoteWorkItemKeyMaps = map[string]RemoteWorkItemMap{
},
ProviderJira: {
AttributeMapper{AttributeExpression(JiraTitle), StringConverter{}}: remoteTitle,
AttributeMapper{AttributeExpression(JiraBody), MarkupConverter{markup: rendering.SystemMarkupJiraWiki}}: remoteDescription,
AttributeMapper{AttributeExpression(JiraBody), MarkupConverter{markup: rendering.SystemMarkupMarkdown}}: remoteDescription,
AttributeMapper{AttributeExpression(JiraState), JiraStateConverter{}}: remoteState,
AttributeMapper{AttributeExpression(JiraID), StringConverter{}}: remoteItemID,
AttributeMapper{AttributeExpression(JiraCreatorLogin), StringConverter{}}: remoteCreatorLogin,
Expand Down
25 changes: 13 additions & 12 deletions remoteworkitem/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import (
)

// TrackerSchedule capture all configuration
type trackerSchedule struct {
TrackerID uuid.UUID
URL string
TrackerType string
Query string
Schedule string
SpaceID uuid.UUID
type TrackerSchedule struct {
TrackerID uuid.UUID
URL string
TrackerType string
Query string
Schedule string
SpaceID uuid.UUID
WorkItemTypeID uuid.UUID
}

// Scheduler represents scheduler
Expand Down Expand Up @@ -67,7 +68,7 @@ func (s *Scheduler) ScheduleAllQueries(ctx context.Context, accessTokens map[str
return errors.WithStack(err)
}
// Convert the remote item into a local work item and persist in the DB.
_, err = ConvertToWorkItemModel(ctx, tx, tq.TrackerID, i, tq.TrackerType, tq.SpaceID)
_, err = ConvertToWorkItemModel(ctx, tx, i, tq)
return errors.WithStack(err)
})
}
Expand All @@ -76,9 +77,9 @@ func (s *Scheduler) ScheduleAllQueries(ctx context.Context, accessTokens map[str
cr.Start()
}

func fetchTrackerQueries(db *gorm.DB) []trackerSchedule {
tsList := []trackerSchedule{}
err := db.Table("tracker_queries").Select("trackers.id as tracker_id, trackers.url, trackers.type as tracker_type, tracker_queries.query, tracker_queries.schedule, tracker_queries.space_id").Joins("left join trackers on tracker_queries.tracker_id = trackers.id").Where("trackers.deleted_at is NULL AND tracker_queries.deleted_at is NULL").Scan(&tsList).Error
func fetchTrackerQueries(db *gorm.DB) []TrackerSchedule {
tsList := []TrackerSchedule{}
err := db.Table("tracker_queries").Select("trackers.id as tracker_id, trackers.url, trackers.type as tracker_type, tracker_queries.query, tracker_queries.schedule, tracker_queries.space_id, tracker_queries.work_item_type_id").Joins("left join trackers on tracker_queries.tracker_id = trackers.id").Where("trackers.deleted_at is NULL AND tracker_queries.deleted_at is NULL").Scan(&tsList).Error
if err != nil {
log.Error(nil, map[string]interface{}{
"err": err,
Expand All @@ -88,7 +89,7 @@ func fetchTrackerQueries(db *gorm.DB) []trackerSchedule {
}

// lookupProvider provides the respective tracker based on the type
func lookupProvider(ts trackerSchedule) TrackerProvider {
func lookupProvider(ts TrackerSchedule) TrackerProvider {
switch ts.TrackerType {
case ProviderGithub:
return &GithubTracker{URL: ts.URL, Query: ts.Query}
Expand Down
6 changes: 3 additions & 3 deletions remoteworkitem/scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import (
func TestLookupProvider(t *testing.T) {
resource.Require(t, resource.UnitTest)

ts1 := trackerSchedule{TrackerType: ProviderGithub}
ts1 := TrackerSchedule{TrackerType: ProviderGithub}
tp1 := lookupProvider(ts1)
require.NotNil(t, tp1)

ts2 := trackerSchedule{TrackerType: ProviderJira}
ts2 := TrackerSchedule{TrackerType: ProviderJira}
tp2 := lookupProvider(ts2)
require.NotNil(t, tp2)

ts3 := trackerSchedule{TrackerType: "unknown"}
ts3 := TrackerSchedule{TrackerType: "unknown"}
tp3 := lookupProvider(ts3)
require.Nil(t, tp3)
}
Loading

0 comments on commit ac1460f

Please sign in to comment.