func TestSearchPagination(t *testing.T) {
	resource.Require(t, resource.Database)
	defer cleaner.DeleteCreatedEntities(DB)()
	service := getServiceAsUser()

	wiRepo := workitem.NewWorkItemRepository(DB)

	_, err := wiRepo.Create(
		context.Background(),
		workitem.SystemBug,
		map[string]interface{}{
			workitem.SystemTitle:       "specialwordforsearch2",
			workitem.SystemDescription: nil,
			workitem.SystemCreator:     "baijum",
			workitem.SystemState:       workitem.SystemStateClosed,
		},
		"")
	require.Nil(t, err)

	controller := NewSearchController(service, gormapplication.NewGormDB(DB))
	q := "specialwordforsearch2"
	_, sr := test.ShowSearchOK(t, nil, nil, controller, nil, nil, q)

	// defaults in paging.go is 'pageSizeDefault = 20'
	assert.Equal(t, "http:///api/search?page[offset]=0&page[limit]=20&q=specialwordforsearch2", *sr.Links.First)
	assert.Equal(t, "http:///api/search?page[offset]=0&page[limit]=20&q=specialwordforsearch2", *sr.Links.Last)
	require.NotEmpty(t, sr.Data)
	r := sr.Data[0]
	assert.Equal(t, "specialwordforsearch2", r.Attributes[workitem.SystemTitle])
}
func TestUnwantedCharactersRelatedToSearchLogic(t *testing.T) {
	resource.Require(t, resource.Database)
	defer cleaner.DeleteCreatedEntities(DB)()
	service := getServiceAsUser()
	wiRepo := workitem.NewWorkItemRepository(DB)

	expectedDescription := rendering.NewMarkupContentFromLegacy("Related to http://example-domain:8080/different-path/ok issue")

	_, err := wiRepo.Create(
		context.Background(),
		workitem.SystemBug,
		map[string]interface{}{
			workitem.SystemTitle:       "specialwordforsearch_new",
			workitem.SystemDescription: expectedDescription,
			workitem.SystemCreator:     "baijum",
			workitem.SystemState:       workitem.SystemStateClosed,
		},
		"")
	require.Nil(t, err)

	controller := NewSearchController(service, gormapplication.NewGormDB(DB))
	// add url: in the query, that is not expected by the code hence need to make sure it gives expected result.
	q := `http://url:some-random-other-domain:8080/different-path/`
	_, sr := test.ShowSearchOK(t, nil, nil, controller, nil, nil, q)
	require.NotNil(t, sr.Data)
	assert.Empty(t, sr.Data)
}
func TestSearch(t *testing.T) {
	resource.Require(t, resource.Database)
	defer cleaner.DeleteCreatedEntities(DB)()

	service := getServiceAsUser()
	wiRepo := workitem.NewWorkItemRepository(DB)

	_, err := wiRepo.Create(
		context.Background(),
		workitem.SystemBug,
		map[string]interface{}{
			workitem.SystemTitle:       "specialwordforsearch",
			workitem.SystemDescription: nil,
			workitem.SystemCreator:     "baijum",
			workitem.SystemState:       workitem.SystemStateClosed,
		},
		"")
	require.Nil(t, err)
	controller := NewSearchController(service, gormapplication.NewGormDB(DB))
	q := "specialwordforsearch"
	_, sr := test.ShowSearchOK(t, nil, nil, controller, nil, nil, q)
	require.NotEmpty(t, sr.Data)
	r := sr.Data[0]
	assert.Equal(t, "specialwordforsearch", r.Attributes[workitem.SystemTitle])
}
func TestSearchURLWithoutPort(t *testing.T) {
	resource.Require(t, resource.Database)
	defer cleaner.DeleteCreatedEntities(DB)()
	service := getServiceAsUser()
	wiRepo := workitem.NewWorkItemRepository(DB)

	description := "This issue is related to http://localhost/detail/876394"
	expectedDescription := rendering.NewMarkupContentFromLegacy(description)
	_, err := wiRepo.Create(
		context.Background(),
		workitem.SystemBug,
		map[string]interface{}{
			workitem.SystemTitle:       "specialwordforsearch_without_port",
			workitem.SystemDescription: expectedDescription,
			workitem.SystemCreator:     "baijum",
			workitem.SystemState:       workitem.SystemStateClosed,
		},
		"")
	require.Nil(t, err)

	controller := NewSearchController(service, gormapplication.NewGormDB(DB))
	q := `"http://localhost/detail/876394"`
	_, sr := test.ShowSearchOK(t, nil, nil, controller, nil, nil, q)
	require.NotEmpty(t, sr.Data)
	r := sr.Data[0]
	assert.Equal(t, description, r.Attributes[workitem.SystemDescription])
}
func TestUnregisteredURLWithPort(t *testing.T) {
	resource.Require(t, resource.Database)
	defer cleaner.DeleteCreatedEntities(DB)()
	service := getServiceAsUser()
	wiRepo := workitem.NewWorkItemRepository(DB)

	description := "Related to http://some-other-domain:8080/different-path/154687364529310/ok issue"
	expectedDescription := rendering.NewMarkupContentFromLegacy(description)
	_, err := wiRepo.Create(
		context.Background(),
		workitem.SystemBug,
		map[string]interface{}{
			workitem.SystemTitle:       "specialwordforsearch_new",
			workitem.SystemDescription: expectedDescription,
			workitem.SystemCreator:     "baijum",
			workitem.SystemState:       workitem.SystemStateClosed,
		},
		"")
	require.Nil(t, err)

	controller := NewSearchController(service, gormapplication.NewGormDB(DB))
	q := `http://some-other-domain:8080/different-path/`
	_, sr := test.ShowSearchOK(t, nil, nil, controller, nil, nil, q)
	require.NotEmpty(t, sr.Data)
	r := sr.Data[0]
	assert.Equal(t, description, r.Attributes[workitem.SystemDescription])
}
// NewWorkItemLinkRepository creates a work item link repository based on gorm
func NewWorkItemLinkRepository(db *gorm.DB) *GormWorkItemLinkRepository {
	return &GormWorkItemLinkRepository{
		db:                   db,
		workItemRepo:         workitem.NewWorkItemRepository(db),
		workItemTypeRepo:     workitem.NewWorkItemTypeRepository(db),
		workItemLinkTypeRepo: NewWorkItemLinkTypeRepository(db),
	}
}
func TestConvertExistingWorkItem(t *testing.T) {
	resource.Require(t, resource.Database)

	// Setting up the dependent tracker query and tracker data in the Database
	tr := Tracker{URL: "https://api.github.com/", Type: ProviderGithub}

	db = db.Create(&tr)
	require.Nil(t, db.Error)

	tq := TrackerQuery{Query: "some random query", Schedule: "0 0 0 * * *", TrackerID: tr.ID}
	db = db.Create(&tq)
	require.Nil(t, db.Error)
	defer cleaner.DeleteCreatedEntities(db)()

	t.Log("Created Tracker Query and Tracker")

	models.Transactional(db, func(tx *gorm.DB) error {
		t.Log("Adding a work item which wasn't present.")

		remoteItemData := TrackerItemContent{
			Content: []byte(`{"title":"linking","url":"http://github.com/sbose/api/testonly/1","state":"closed","body":"body of issue","user.login":"******","assignee.login":"******"}`),
			ID:      "http://github.com/sbose/api/testonly/1",
		}

		workItem, err := convert(tx, int(tq.ID), remoteItemData, ProviderGithub)

		assert.Nil(t, err)
		assert.Equal(t, "linking", workItem.Fields[workitem.SystemTitle])
		assert.Equal(t, "sbose78", workItem.Fields[workitem.SystemCreator])
		assert.Equal(t, "pranav", workItem.Fields[workitem.SystemAssignees].([]interface{})[0])
		assert.Equal(t, "closed", workItem.Fields[workitem.SystemState])
		return errors.WithStack(err)
	})

	t.Log("Updating the existing work item when it's reimported.")

	models.Transactional(db, func(tx *gorm.DB) error {
		remoteItemDataUpdated := TrackerItemContent{
			Content: []byte(`{"title":"linking-updated","url":"http://github.com/api/testonly/1","state":"closed","body":"body of issue","user.login":"******","assignee.login":"******"}`),
			ID:      "http://github.com/sbose/api/testonly/1",
		}
		workItemUpdated, err := convert(tx, int(tq.ID), remoteItemDataUpdated, ProviderGithub)

		assert.Nil(t, err)
		assert.Equal(t, "linking-updated", workItemUpdated.Fields[workitem.SystemTitle])
		assert.Equal(t, "sbose78", workItemUpdated.Fields[workitem.SystemCreator])
		assert.Equal(t, "pranav", workItemUpdated.Fields[workitem.SystemAssignees].([]interface{})[0])
		assert.Equal(t, "closed", workItemUpdated.Fields[workitem.SystemState])

		wir := workitem.NewWorkItemRepository(tx)
		wir.Delete(context.Background(), workItemUpdated.ID)

		return errors.WithStack(err)
	})
}
func (s *searchRepositoryWhiteboxTest) TestSearchByID() {

	models.Transactional(s.DB, func(tx *gorm.DB) error {
		wir := workitem.NewWorkItemRepository(tx)

		workItem := app.WorkItem{Fields: make(map[string]interface{})}

		workItem.Fields = map[string]interface{}{
			workitem.SystemTitle:       "Search Test Sbose",
			workitem.SystemDescription: rendering.NewMarkupContentFromLegacy("Description"),
			workitem.SystemCreator:     "sbose78",
			workitem.SystemAssignees:   []string{"pranav"},
			workitem.SystemState:       "closed",
		}

		createdWorkItem, err := wir.Create(context.Background(), workitem.SystemBug, workItem.Fields, testsupport.TestIdentity.ID.String())
		if err != nil {
			s.T().Fatalf("Couldn't create test data: %+v", err)
		}
		defer wir.Delete(context.Background(), createdWorkItem.ID)

		// Create a new workitem to have the ID in it's title. This should not come
		// up in search results

		workItem.Fields[workitem.SystemTitle] = "Search test sbose " + createdWorkItem.ID
		_, err = wir.Create(context.Background(), workitem.SystemBug, workItem.Fields, testsupport.TestIdentity.ID.String())
		if err != nil {
			s.T().Fatalf("Couldn't create test data: %+v", err)
		}

		sr := NewGormSearchRepository(tx)

		var start, limit int = 0, 100
		searchString := "id:" + createdWorkItem.ID
		workItemList, _, err := sr.SearchFullText(context.Background(), searchString, &start, &limit)
		if err != nil {
			s.T().Fatal("Error gettig search result ", err)
		}

		// ID is unique, hence search result set's length should be 1
		assert.Equal(s.T(), len(workItemList), 1)
		for _, workItemValue := range workItemList {
			s.T().Log("Found search result for ID Search ", workItemValue.ID)
			assert.Equal(s.T(), createdWorkItem.ID, workItemValue.ID)
		}
		return errors.WithStack(err)
	})
}
func (rest *TestSpaceIterationREST) TestWICountsWithIterationListBySpace() {
	t := rest.T()
	resource.Require(t, resource.Database)
	// create seed data
	spaceRepo := space.NewRepository(rest.DB)
	spaceInstance := space.Space{
		Name: "Testing space",
	}
	spaceRepo.Create(context.Background(), &spaceInstance)
	fmt.Println("space id = ", spaceInstance.ID)
	assert.NotEqual(rest.T(), uuid.UUID{}, spaceInstance.ID)

	iterationRepo := iteration.NewIterationRepository(rest.DB)
	iteration1 := iteration.Iteration{
		Name:    "Sprint 1",
		SpaceID: spaceInstance.ID,
	}
	iterationRepo.Create(context.Background(), &iteration1)
	fmt.Println("iteration1 id = ", iteration1.ID)
	assert.NotEqual(rest.T(), uuid.UUID{}, iteration1.ID)

	iteration2 := iteration.Iteration{
		Name:    "Sprint 2",
		SpaceID: spaceInstance.ID,
	}
	iterationRepo.Create(context.Background(), &iteration2)
	fmt.Println("iteration2 id = ", iteration2.ID)
	assert.NotEqual(rest.T(), uuid.UUID{}, iteration2.ID)

	wirepo := workitem.NewWorkItemRepository(rest.DB)

	for i := 0; i < 3; i++ {
		wirepo.Create(
			context.Background(), workitem.SystemBug,
			map[string]interface{}{
				workitem.SystemTitle:     fmt.Sprintf("New issue #%d", i),
				workitem.SystemState:     workitem.SystemStateNew,
				workitem.SystemIteration: iteration1.ID.String(),
			}, "xx")
	}
	for i := 0; i < 2; i++ {
		wirepo.Create(
			context.Background(), workitem.SystemBug,
			map[string]interface{}{
				workitem.SystemTitle:     fmt.Sprintf("Closed issue #%d", i),
				workitem.SystemState:     workitem.SystemStateClosed,
				workitem.SystemIteration: iteration1.ID.String(),
			}, "xx")
	}

	svc, ctrl := rest.UnSecuredController()
	_, cs := test.ListSpaceIterationsOK(t, svc.Context, svc, ctrl, spaceInstance.ID.String())
	assert.Len(t, cs.Data, 2)
	for _, iterationItem := range cs.Data {
		if iterationItem.ID.String() == iteration1.ID.String() {
			assert.Equal(t, 5, iterationItem.Relationships.Workitems.Meta["total"])
			assert.Equal(t, 2, iterationItem.Relationships.Workitems.Meta["closed"])
		} else if iterationItem.ID.String() == iteration2.ID.String() {
			assert.Equal(t, 0, iterationItem.Relationships.Workitems.Meta["total"])
			assert.Equal(t, 0, iterationItem.Relationships.Workitems.Meta["closed"])
		}
	}
	// seed 5 WI to iteration2
	for i := 0; i < 5; i++ {
		wirepo.Create(
			context.Background(), workitem.SystemBug,
			map[string]interface{}{
				workitem.SystemTitle:     fmt.Sprintf("New issue #%d", i),
				workitem.SystemState:     workitem.SystemStateNew,
				workitem.SystemIteration: iteration2.ID.String(),
			}, "xx")
	}
	_, cs = test.ListSpaceIterationsOK(t, svc.Context, svc, ctrl, spaceInstance.ID.String())
	assert.Len(t, cs.Data, 2)
	for _, iterationItem := range cs.Data {
		if iterationItem.ID.String() == iteration1.ID.String() {
			assert.Equal(t, 5, iterationItem.Relationships.Workitems.Meta["total"])
			assert.Equal(t, 2, iterationItem.Relationships.Workitems.Meta["closed"])
		} else if iterationItem.ID.String() == iteration2.ID.String() {
			assert.Equal(t, 5, iterationItem.Relationships.Workitems.Meta["total"])
			assert.Equal(t, 0, iterationItem.Relationships.Workitems.Meta["closed"])
		}
	}
}
func (s *searchRepositoryWhiteboxTest) TestSearchByText() {
	wir := workitem.NewWorkItemRepository(s.DB)

	testDataSet := []SearchTestDescriptor{
		{
			wi: app.WorkItem{
				Fields: map[string]interface{}{
					workitem.SystemTitle:       "test sbose title '12345678asdfgh'",
					workitem.SystemDescription: rendering.NewMarkupContentFromLegacy(`"description" for search test`),
					workitem.SystemCreator:     "sbose78",
					workitem.SystemAssignees:   []string{"pranav"},
					workitem.SystemState:       "closed",
				},
			},
			searchString:   `Sbose "deScription" '12345678asdfgh' `,
			minimumResults: 1,
		},
		{
			wi: app.WorkItem{
				Fields: map[string]interface{}{
					workitem.SystemTitle:       "add new error types in models/errors.go'",
					workitem.SystemDescription: rendering.NewMarkupContentFromLegacy(`Make sure remoteworkitem can access..`),
					workitem.SystemCreator:     "sbose78",
					workitem.SystemAssignees:   []string{"pranav"},
					workitem.SystemState:       "closed",
				},
			},
			searchString:   `models/errors.go remoteworkitem `,
			minimumResults: 1,
		},
		{
			wi: app.WorkItem{
				Fields: map[string]interface{}{
					workitem.SystemTitle:       "test sbose title '12345678asdfgh'",
					workitem.SystemDescription: rendering.NewMarkupContentFromLegacy(`"description" for search test`),
					workitem.SystemCreator:     "sbose78",
					workitem.SystemAssignees:   []string{"pranav"},
					workitem.SystemState:       "closed",
				},
			},
			searchString:   `Sbose "deScription" '12345678asdfgh' `,
			minimumResults: 1,
		},
		{
			wi: app.WorkItem{
				// will test behaviour when null fields are present. In this case, "system.description" is nil
				Fields: map[string]interface{}{
					workitem.SystemTitle:     "test nofield sbose title '12345678asdfgh'",
					workitem.SystemCreator:   "sbose78",
					workitem.SystemAssignees: []string{"pranav"},
					workitem.SystemState:     "closed",
				},
			},
			searchString:   `sbose nofield `,
			minimumResults: 1,
		},
		{
			wi: app.WorkItem{
				// will test behaviour when null fields are present. In this case, "system.description" is nil
				Fields: map[string]interface{}{
					workitem.SystemTitle:     "test should return 0 results'",
					workitem.SystemCreator:   "sbose78",
					workitem.SystemAssignees: []string{"pranav"},
					workitem.SystemState:     "closed",
				},
			},
			searchString:   `negative case `,
			minimumResults: 0,
		}, {
			wi: app.WorkItem{
				// search stirng with braces should be acceptable case
				Fields: map[string]interface{}{
					workitem.SystemTitle:     "Bug reported by administrator for input = (value)",
					workitem.SystemCreator:   "pgore",
					workitem.SystemAssignees: []string{"pranav"},
					workitem.SystemState:     "new",
				},
			},
			searchString:   `(value) `,
			minimumResults: 1,
		}, {
			wi: app.WorkItem{
				// search stirng with surrounding braces should be acceptable case
				Fields: map[string]interface{}{
					workitem.SystemTitle:     "trial for braces (pranav) {shoubhik} [aslak]",
					workitem.SystemCreator:   "pgore",
					workitem.SystemAssignees: []string{"pranav"},
					workitem.SystemState:     "new",
				},
			},
			searchString:   `(pranav) {shoubhik} [aslak] `,
			minimumResults: 1,
		},
	}

	models.Transactional(s.DB, func(tx *gorm.DB) error {

		for _, testData := range testDataSet {
			workItem := testData.wi
			searchString := testData.searchString
			minimumResults := testData.minimumResults
			workItemURLInSearchString := "http://demo.almighty.io/work-item/list/detail/"

			createdWorkItem, err := wir.Create(context.Background(), workitem.SystemBug, workItem.Fields, testsupport.TestIdentity.ID.String())
			if err != nil {
				s.T().Fatal("Couldnt create test data")
			}

			defer wir.Delete(context.Background(), createdWorkItem.ID)

			// create the URL and use it in the search string
			workItemURLInSearchString = workItemURLInSearchString + createdWorkItem.ID

			// had to dynamically create this since I didn't now the URL/ID of the workitem
			// till the test data was created.
			searchString = searchString + workItemURLInSearchString
			searchString = fmt.Sprintf("\"%s\"", searchString)
			s.T().Log("using search string: " + searchString)
			sr := NewGormSearchRepository(tx)
			var start, limit int = 0, 100
			workItemList, _, err := sr.SearchFullText(context.Background(), searchString, &start, &limit)
			if err != nil {
				s.T().Fatal("Error getting search result ", err)
			}
			searchString = strings.Trim(searchString, "\"")
			// Since this test adds test data, whether or not other workitems exist
			// there must be at least 1 search result returned.
			if len(workItemList) == minimumResults && minimumResults == 0 {
				// no point checking further, we got what we wanted.
				continue
			} else if len(workItemList) < minimumResults {
				s.T().Fatalf("At least %d search results was expected ", minimumResults)
			}

			// These keywords need a match in the textual part.
			allKeywords := strings.Fields(searchString)
			allKeywords = append(allKeywords, createdWorkItem.ID)
			//[]string{workItemURLInSearchString, createdWorkItem.ID, `"Sbose"`, `"deScription"`, `'12345678asdfgh'`}

			// These keywords need a match optionally either as URL string or ID
			optionalKeywords := []string{workItemURLInSearchString, createdWorkItem.ID}

			// We will now check the legitimacy of the search results.
			// Iterate through all search results and see whether they meet the criteria

			for _, workItemValue := range workItemList {
				s.T().Log("Found search result  ", workItemValue.ID)

				for _, keyWord := range allKeywords {

					workItemTitle := ""
					if workItemValue.Fields[workitem.SystemTitle] != nil {
						workItemTitle = strings.ToLower(workItemValue.Fields[workitem.SystemTitle].(string))
					}
					workItemDescription := ""
					if workItemValue.Fields[workitem.SystemDescription] != nil {
						descriptionField := workItemValue.Fields[workitem.SystemDescription].(rendering.MarkupContent)
						workItemDescription = strings.ToLower(descriptionField.Content)
					}
					keyWord = strings.ToLower(keyWord)

					if strings.Contains(workItemTitle, keyWord) || strings.Contains(workItemDescription, keyWord) {
						// Check if the search keyword is present as text in the title/description
						s.T().Logf("Found keyword %s in workitem %s", keyWord, workItemValue.ID)
					} else if stringInSlice(keyWord, optionalKeywords) && strings.Contains(keyWord, workItemValue.ID) {
						// If not present in title/description then it should be a URL or ID
						s.T().Logf("Found keyword %s as ID %s from the URL", keyWord, workItemValue.ID)
					} else {
						s.T().Errorf("%s neither found in title %s nor in the description: %s", keyWord, workItemTitle, workItemDescription)
					}
				}
				//defer wir.Delete(context.Background(), workItemValue.ID)
			}

		}
		return nil

	})
}
// Map a remote work item into an ALM work item and persist it into the database.
func convert(db *gorm.DB, tID int, item TrackerItemContent, provider string) (*app.WorkItem, error) {
	remoteID := item.ID
	content := string(item.Content)

	wir := workitem.NewWorkItemRepository(db)
	ti := TrackerItem{Item: content, RemoteItemID: remoteID, TrackerID: uint64(tID)}

	// Converting the remote item to a local work item
	remoteTrackerItemMethodRef, ok := RemoteWorkItemImplRegistry[provider]
	if !ok {
		return nil, BadParameterError{parameter: provider, value: provider}
	}
	remoteTrackerItem, err := remoteTrackerItemMethodRef(ti)
	if err != nil {
		return nil, InternalError{simpleError{message: " Error parsing the tracker data "}}
	}
	workItem, err := Map(remoteTrackerItem, WorkItemKeyMaps[provider])
	if err != nil {
		return nil, ConversionError{simpleError{message: " Error mapping to local work item "}}
	}

	// Get the remote item identifier ( which is currently the url ) to check if the work item exists in the database.
	workItemRemoteID := workItem.Fields[workitem.SystemRemoteItemID]

	sqlExpression := criteria.Equals(criteria.Field(workitem.SystemRemoteItemID), criteria.Literal(workItemRemoteID))

	var newWorkItem *app.WorkItem

	// Querying the database
	existingWorkItems, _, err := wir.List(context.Background(), sqlExpression, nil, nil)
	if err != nil {
		return nil, err
	}

	if len(existingWorkItems) != 0 {
		log.Info(nil, map[string]interface{}{
			"pkg":      "remoteworkitem",
			"workitem": workItem,
		}, "Workitem exists, will be updated")

		existingWorkItem := existingWorkItems[0]
		for key, value := range workItem.Fields {
			existingWorkItem.Fields[key] = value
		}
		newWorkItem, err = wir.Save(context.Background(), *existingWorkItem)
		if err != nil {
			log.Error(nil, map[string]interface{}{
				"existingWorkitem": existingWorkItem,
				"err":              err,
			}, "unable to update the work item")
		}
	} else {
		log.Info(nil, map[string]interface{}{
			"pkg":           "remoteworkitem",
			"sqlExpression": sqlExpression,
			"err":           err,
		}, "Work item not found , will now create new work item")
		c := workItem.Fields[workitem.SystemCreator]
		var creator string
		if c != nil {
			creator = c.(string)
		}
		newWorkItem, err = wir.Create(context.Background(), workitem.SystemBug, workItem.Fields, creator)
		if err != nil {
			log.Error(nil, map[string]interface{}{
				"creator":            creator,
				"workItem.Fields":    workItem.Fields,
				"workitem.SystemBug": workitem.SystemBug,
				"err":                err,
			}, "unable to create the work item")
		}
	}
	return newWorkItem, errors.WithStack(err)
}
func (s *workItemRepoBlackBoxTest) SetupTest() {
	s.repo = workitem.NewWorkItemRepository(s.DB)
}
func (s *searchRepositoryBlackboxTest) TestRestrictByType() {
	resource.Require(s.T(), resource.Database)
	undoScript := &gormsupport.DBScript{}
	defer undoScript.Run(s.DB)
	typeRepo := workitem.NewUndoableWorkItemTypeRepository(workitem.NewWorkItemTypeRepository(s.DB), undoScript)
	wiRepo := workitem.NewUndoableWorkItemRepository(workitem.NewWorkItemRepository(s.DB), undoScript)
	searchRepo := search.NewGormSearchRepository(s.DB)

	ctx := context.Background()
	res, count, err := searchRepo.SearchFullText(ctx, "TestRestrictByType", nil, nil)
	require.Nil(s.T(), err)
	require.True(s.T(), count == uint64(len(res))) // safety check for many, many instances of bogus search results.
	for _, wi := range res {
		wiRepo.Delete(ctx, wi.ID)
	}

	s.DB.Unscoped().Delete(&workitem.WorkItemType{Name: "base"})
	s.DB.Unscoped().Delete(&workitem.WorkItemType{Name: "sub1"})
	s.DB.Unscoped().Delete(&workitem.WorkItemType{Name: "subtwo"})

	extended := workitem.SystemBug
	base, err := typeRepo.Create(ctx, &extended, "base", map[string]app.FieldDefinition{})
	require.NotNil(s.T(), base)
	require.Nil(s.T(), err)

	extended = "base"
	sub1, err := typeRepo.Create(ctx, &extended, "sub1", map[string]app.FieldDefinition{})
	require.NotNil(s.T(), sub1)
	require.Nil(s.T(), err)

	sub2, err := typeRepo.Create(ctx, &extended, "subtwo", map[string]app.FieldDefinition{})
	require.NotNil(s.T(), sub2)
	require.Nil(s.T(), err)

	wi1, err := wiRepo.Create(ctx, "sub1", map[string]interface{}{
		workitem.SystemTitle: "Test TestRestrictByType",
		workitem.SystemState: "closed",
	}, testsupport.TestIdentity.ID.String())
	require.NotNil(s.T(), wi1)
	require.Nil(s.T(), err)

	wi2, err := wiRepo.Create(ctx, "subtwo", map[string]interface{}{
		workitem.SystemTitle: "Test TestRestrictByType 2",
		workitem.SystemState: "closed",
	}, testsupport.TestIdentity.ID.String())
	require.NotNil(s.T(), wi2)
	require.Nil(s.T(), err)

	res, count, err = searchRepo.SearchFullText(ctx, "TestRestrictByType", nil, nil)
	assert.Nil(s.T(), err)
	assert.Equal(s.T(), uint64(2), count)

	res, count, err = searchRepo.SearchFullText(ctx, "TestRestrictByType type:sub1", nil, nil)
	assert.Nil(s.T(), err)
	assert.Equal(s.T(), uint64(1), count)
	if count == 1 {
		assert.Equal(s.T(), wi1.ID, res[0].ID)
	}

	res, count, err = searchRepo.SearchFullText(ctx, "TestRestrictByType type:subtwo", nil, nil)
	assert.Nil(s.T(), err)
	assert.Equal(s.T(), uint64(1), count)
	if count == 1 {
		assert.Equal(s.T(), wi2.ID, res[0].ID)
	}

	_, count, err = searchRepo.SearchFullText(ctx, "TestRestrictByType type:base", nil, nil)
	assert.Nil(s.T(), err)
	assert.Equal(s.T(), uint64(2), count)

	_, count, err = searchRepo.SearchFullText(ctx, "TestRestrictByType type:subtwo type:sub1", nil, nil)
	assert.Nil(s.T(), err)
	assert.Equal(s.T(), uint64(2), count)

	_, count, err = searchRepo.SearchFullText(ctx, "TestRestrictByType type:base type:sub1", nil, nil)
	assert.Nil(s.T(), err)
	assert.Equal(s.T(), uint64(2), count)

	_, count, err = searchRepo.SearchFullText(ctx, "TRBTgorxi type:base", nil, nil)
	assert.Nil(s.T(), err)
	assert.Equal(s.T(), uint64(0), count)
}
Exemple #14
0
func (g *GormBase) WorkItems() workitem.WorkItemRepository {
	return workitem.NewWorkItemRepository(g.db)
}