func TestAddLGTMIfCommented(t *testing.T) {
	runtime.GOMAXPROCS(runtime.NumCPU())

	tests := []struct {
		name        string
		comments    []*github.IssueComment
		issue       *github.Issue
		assignees   mungerutil.UserSet
		mustHave    []string
		mustNotHave []string
	}{
		{
			name:  "Other comments should not add LGTM.",
			issue: prWithoutLGTM,
			comments: []*github.IssueComment{
				github_test.IssueComment(1, "/comment 1", "user 1", 0),
				github_test.IssueComment(2, "/comment 2 //comment3", "user 2", 1),
			},
			assignees:   mungerutil.UserSet(sets.NewString("user 1")),
			mustHave:    []string{},
			mustNotHave: []string{lgtmLabel},
		},
		{
			name:  "/lgtm by non-assignee should not add LGTM label",
			issue: prWithoutLGTM,
			comments: []*github.IssueComment{
				github_test.IssueComment(1, "/lgtm", "user 1", 0),
				github_test.IssueComment(2, "comment 2", "user 2", 1),
			},
			assignees:   mungerutil.UserSet(sets.NewString("user 2")),
			mustHave:    []string{},
			mustNotHave: []string{lgtmLabel},
		},
		{
			name:  "/lgtm by assignee should add LGTM label",
			issue: prWithoutLGTM,
			comments: []*github.IssueComment{
				github_test.IssueComment(1, "/lgtm", "user 1", 0),
				github_test.IssueComment(2, "comment 2", "user 2", 1),
			},
			assignees:   mungerutil.UserSet(sets.NewString("user 1")),
			mustHave:    []string{lgtmLabel},
			mustNotHave: []string{},
		},
		{
			name:  "/lgtm by assignee followed by cancellation by non-assignee should add lgtm",
			issue: prWithoutLGTM,
			comments: []*github.IssueComment{
				github_test.IssueComment(1, "/lgtm", "user 1", 0),
				github_test.IssueComment(2, "/lgtm cancel", "user 2", 1),
			},
			assignees:   mungerutil.UserSet(sets.NewString("user 1")),
			mustHave:    []string{lgtmLabel},
			mustNotHave: []string{},
		},
		{
			name:  "/lgtm by assignee followed by /lgtm cancel should not add lgtm",
			issue: prWithoutLGTM,
			comments: []*github.IssueComment{
				github_test.IssueComment(1, "/lgtm", "user 1", 0),
				github_test.IssueComment(2, "/lgtm cancel", "user 2", 1),
			},
			assignees:   mungerutil.UserSet(sets.NewString("user 1", "user 2")),
			mustHave:    []string{},
			mustNotHave: []string{lgtmLabel},
		},
		{
			name:  "/lgtm followed by comment should be honored",
			issue: prWithoutLGTM,
			comments: []*github.IssueComment{
				github_test.IssueComment(1, "/lgtm //this is a comment", "user 1", 0),
			},
			assignees:   mungerutil.UserSet(sets.NewString("user 1")),
			mustHave:    []string{lgtmLabel},
			mustNotHave: []string{},
		},
		{
			name:  "/lgtm cancel by bot should be honored",
			issue: prWithoutLGTM,
			comments: []*github.IssueComment{
				github_test.IssueComment(1, "/lgtm //this is a comment", "user 1", 0),
				github_test.IssueComment(1, "/lgtm cancel //this is a bot", botName, 0),
			},
			assignees:   mungerutil.UserSet(sets.NewString("user 1")),
			mustHave:    []string{},
			mustNotHave: []string{lgtmLabel},
		},
	}

	for testNum, test := range tests {
		pr := ValidPR()
		client, server, mux := github_test.InitServer(t, test.issue, pr, nil, nil, nil, nil, nil)
		path := fmt.Sprintf("/repos/o/r/issue/%s/labels", *test.issue.Number)
		mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
			w.WriteHeader(http.StatusOK)
			out := []github.Label{{}}
			data, err := json.Marshal(out)
			if err != nil {
				t.Errorf("Unexpected error: %v", err)
			}
			w.Write(data)
		})

		config := &github_util.Config{}
		config.Org = "o"
		config.Project = "r"
		config.SetClient(client)

		l := LGTMHandler{}
		obj, err := config.GetObject(*test.issue.Number)
		if err != nil {
			t.Fatalf("%v", err)
		}

		l.addLGTMIfCommented(obj, test.comments, test.assignees)
		for _, lab := range test.mustHave {
			if !obj.HasLabel(lab) {
				t.Errorf("%s:%d: Did not find label %q, labels: %v", test.name, testNum, lab, obj.Issue.Labels)
			}
		}
		for _, lab := range test.mustNotHave {
			if obj.HasLabel(lab) {
				t.Errorf("%s:%d: Found label %q and should not have, labels: %v", test.name, testNum, lab, obj.Issue.Labels)
			}
		}
		server.Close()
	}
}
func TestAssignComment(t *testing.T) {
	runtime.GOMAXPROCS(runtime.NumCPU())

	tests := []struct {
		testName          string
		comments          []*goGithub.IssueComment
		existingAssignees []*goGithub.User
		newAssignees      sets.String
		removedAssignees  sets.String
	}{
		{
			testName: "Assign cmd should add to existing assignees",
			comments: []*goGithub.IssueComment{
				github_test.IssueComment(1, assignCommand, "user 1", 0),
			},
			existingAssignees: []*goGithub.User{},
			newAssignees:      sets.NewString("user 1"),
			removedAssignees:  sets.NewString(),
		},
		{
			testName: "Assign cmd should not modify existing assignees",
			comments: []*goGithub.IssueComment{
				github_test.IssueComment(1, assignCommand, "user 1", 0),
			},
			existingAssignees: []*goGithub.User{{Login: testUser.Name}},
			newAssignees:      sets.NewString("user 1"),
			removedAssignees:  sets.NewString(),
		},
		{
			testName: "Unassign should remove existing assignee",
			comments: []*goGithub.IssueComment{
				github_test.IssueComment(1, unassignCommand, *testUser.Name, 0),
			},
			existingAssignees: []*goGithub.User{{Login: testUser.Name}},
			newAssignees:      sets.NewString(""),
			removedAssignees:  sets.NewString(*testUser.Name),
		},
		{
			testName: "Reassign by someone else should leave assignees in tact",
			comments: []*goGithub.IssueComment{
				github_test.IssueComment(2, unassignCommand, "NotAUser", 1),
			},
			existingAssignees: []*goGithub.User{{Login: testUser.Name}},
			newAssignees:      sets.NewString(),
			removedAssignees:  sets.NewString(),
		},
	}

	for testNum, test := range tests {
		pr := github.MungeObject{}
		pr.Issue = &goGithub.Issue{}
		pr.Issue.Assignees = test.existingAssignees
		ah := AssignUnassignHandler{}
		assignees, unassignees := ah.getAssigneesAndUnassignees(&pr, test.comments, []*goGithub.CommitFile{}, weightMap{"user 1": 1})
		if assignees.Difference(test.newAssignees).Len() != 0 {
			t.Errorf("For test %v, the expected new assignees did not match the returned new assignees %v %v", testNum, test.newAssignees, assignees)
		}
		if unassignees.Difference(test.removedAssignees).Len() != 0 {
			t.Errorf("Existing Assignees %v", *pr.Issue.Assignees[0])
			t.Errorf("For test %v, the expected removed assignees %v actual removed assignees %v", testNum, test.removedAssignees, unassignees)
		}
	}
}