func TestConvertJSONAPIToWorkItemWithDescriptionContentNoMarkup(t *testing.T) {
	appl := new(application.Application)
	attributes := map[string]interface{}{
		workitem.SystemTitle:       "title",
		workitem.SystemDescription: rendering.NewMarkupContentFromLegacy("description"),
	}
	source := app.WorkItem2{Type: workitem.SystemBug, Attributes: attributes}
	target := &app.WorkItem{Fields: map[string]interface{}{}}
	err := ConvertJSONAPIToWorkItem(*appl, source, target)
	require.Nil(t, err)
	require.NotNil(t, target)
	require.NotNil(t, target.Fields)
	expectedDescription := rendering.NewMarkupContentFromLegacy("description")
	assert.Equal(t, expectedDescription, target.Fields[workitem.SystemDescription])
}
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 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])
}
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 (s *workItemRepoBlackBoxTest) TestCreateWorkItemWithDescriptionNoMarkup() {
	defer cleaner.DeleteCreatedEntities(s.DB)()

	wi, err := s.repo.Create(
		context.Background(), workitem.SystemBug,
		map[string]interface{}{
			workitem.SystemTitle:       "Title",
			workitem.SystemDescription: rendering.NewMarkupContentFromLegacy("Description"),
			workitem.SystemState:       workitem.SystemStateNew,
		}, "xx")
	require.Nil(s.T(), err, "Could not create workitem")

	wi, err = s.repo.Load(context.Background(), wi.ID)
	require.Nil(s.T(), err)
	// app.WorkItem does not contain the markup associated with the description (yet)
	assert.Equal(s.T(), rendering.NewMarkupContentFromLegacy("Description"), wi.Fields[workitem.SystemDescription])
}
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 (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

	})
}