Repository: xanzy/go-gitlab
Pull request #526 (2018-12-02 07:58:29)

Added unit test for issues and settings

svanharmelen: Thanks @Snehal1112! LGMT!

Patch:
diff --git a/issues.go b/issues.go
index fc999c0..7574b1d 100644
--- a/issues.go
+++ b/issues.go
@@ -33,62 +33,64 @@ type IssuesService struct {
 	timeStats *timeStatsService
 }
 
+// IssueAuthor represents a author of the issue.
+type IssueAuthor struct {
+	ID        int    `json:"id"`
+	State     string `json:"state"`
+	WebURL    string `json:"web_url"`
+	Name      string `json:"name"`
+	AvatarURL string `json:"avatar_url"`
+	Username  string `json:"username"`
+}
+
+// IssueAssignee represents a assignee of the issue.
+type IssueAssignee struct {
+	ID        int    `json:"id"`
+	State     string `json:"state"`
+	WebURL    string `json:"web_url"`
+	Name      string `json:"name"`
+	AvatarURL string `json:"avatar_url"`
+	Username  string `json:"username"`
+}
+
+// IssueLinks represents links of the issue.
+type IssueLinks struct {
+	Self       string `json:"self"`
+	Notes      string `json:"notes"`
+	AwardEmoji string `json:"award_emoji"`
+	Project    string `json:"project"`
+}
+
 // Issue represents a GitLab issue.
 //
 // GitLab API docs: https://docs.gitlab.com/ce/api/issues.html
 type Issue struct {
-	ID        int        `json:"id"`
-	IID       int        `json:"iid"`
-	ProjectID int        `json:"project_id"`
-	Milestone *Milestone `json:"milestone"`
-	Author    struct {
-		ID        int    `json:"id"`
-		State     string `json:"state"`
-		WebURL    string `json:"web_url"`
-		Name      string `json:"name"`
-		AvatarURL string `json:"avatar_url"`
-		Username  string `json:"username"`
-	} `json:"author"`
-	Description string `json:"description"`
-	State       string `json:"state"`
-	Assignees   []struct {
-		ID        int    `json:"id"`
-		State     string `json:"state"`
-		WebURL    string `json:"web_url"`
-		Name      string `json:"name"`
-		AvatarURL string `json:"avatar_url"`
-		Username  string `json:"username"`
-	} `json:"assignees"`
-	Assignee struct {
-		ID        int    `json:"id"`
-		State     string `json:"state"`
-		WebURL    string `json:"web_url"`
-		Name      string `json:"name"`
-		AvatarURL string `json:"avatar_url"`
-		Username  string `json:"username"`
-	} `json:"assignee"`
-	Upvotes          int        `json:"upvotes"`
-	Downvotes        int        `json:"downvotes"`
-	Labels           []string   `json:"labels"`
-	Title            string     `json:"title"`
-	UpdatedAt        *time.Time `json:"updated_at"`
-	CreatedAt        *time.Time `json:"created_at"`
-	ClosedAt         *time.Time `json:"closed_at"`
-	Subscribed       bool       `json:"subscribed"`
-	UserNotesCount   int        `json:"user_notes_count"`
-	DueDate          *ISOTime   `json:"due_date"`
-	WebURL           string     `json:"web_url"`
-	TimeStats        *TimeStats `json:"time_stats"`
-	Confidential     bool       `json:"confidential"`
-	Weight           int        `json:"weight"`
-	DiscussionLocked bool       `json:"discussion_locked"`
-	Links            struct {
-		Self       string `json:"self"`
-		Notes      string `json:"notes"`
-		AwardEmoji string `json:"award_emoji"`
-		Project    string `json:"project"`
-	} `json:"_links"`
-	IssueLinkID int `json:"issue_link_id"`
+	ID               int              `json:"id"`
+	IID              int              `json:"iid"`
+	ProjectID        int              `json:"project_id"`
+	Milestone        *Milestone       `json:"milestone"`
+	Author           *IssueAuthor     `json:"author"`
+	Description      string           `json:"description"`
+	State            string           `json:"state"`
+	Assignees        []*IssueAssignee `json:"assignees"`
+	Assignee         *IssueAssignee   `json:"assignee"`
+	Upvotes          int              `json:"upvotes"`
+	Downvotes        int              `json:"downvotes"`
+	Labels           []string         `json:"labels"`
+	Title            string           `json:"title"`
+	UpdatedAt        *time.Time       `json:"updated_at"`
+	CreatedAt        *time.Time       `json:"created_at"`
+	ClosedAt         *time.Time       `json:"closed_at"`
+	Subscribed       bool             `json:"subscribed"`
+	UserNotesCount   int              `json:"user_notes_count"`
+	DueDate          *ISOTime         `json:"due_date"`
+	WebURL           string           `json:"web_url"`
+	TimeStats        *TimeStats       `json:"time_stats"`
+	Confidential     bool             `json:"confidential"`
+	Weight           int              `json:"weight"`
+	DiscussionLocked bool             `json:"discussion_locked"`
+	Links            *IssueLinks      `json:"_links"`
+	IssueLinkID      int              `json:"issue_link_id"`
 }
 
 func (i Issue) String() string {


Test patch:
diff --git a/issues_test.go b/issues_test.go
new file mode 100644
index 0000000..e1b38d9
--- /dev/null
+++ b/issues_test.go
@@ -0,0 +1,402 @@
+package gitlab
+
+import (
+	"fmt"
+	"log"
+	"net/http"
+	"reflect"
+	"testing"
+)
+
+func TestGetIssue(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{"id":1, "description": "This is test project", "author" : {"id" : 1, "name": "snehal"}, "assignees":[{"id":1}]}`)
+	})
+
+	issue, _, err := client.Issues.GetIssue("1", 5)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := &Issue{
+		ID:          1,
+		Description: "This is test project",
+		Author:      &IssueAuthor{ID: 1, Name: "snehal"},
+		Assignees:   []*IssueAssignee{{ID: 1}},
+	}
+
+	if !reflect.DeepEqual(want, issue) {
+		t.Errorf("Issues.GetIssue returned %+v, want %+v", issue, want)
+	}
+}
+
+func TestDeleteIssue(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "DELETE")
+		fmt.Fprint(w, `{"id":1, "description": "This is test project", "author" : {"id" : 1, "name": "snehal"}, "assignees":[{"id":1}]}`)
+	})
+
+	_, err := client.Issues.DeleteIssue("1", 5)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func TestListIssues(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/issues", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testURL(t, r, "/api/v4/issues?assignee_id=2&author_id=1")
+		fmt.Fprint(w, `[{"id":1, "description": "This is test project", "author" : {"id" : 1, "name": "snehal"}, "assignees":[{"id":1}]}]`)
+	})
+
+	listProjectIssue := &ListIssuesOptions{
+		AuthorID:   Int(01),
+		AssigneeID: Int(02),
+	}
+
+	issues, _, err := client.Issues.ListIssues(listProjectIssue)
+
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := []*Issue{{
+		ID:          1,
+		Description: "This is test project",
+		Author:      &IssueAuthor{ID: 1, Name: "snehal"},
+		Assignees:   []*IssueAssignee{{ID: 1}},
+	}}
+
+	if !reflect.DeepEqual(want, issues) {
+		t.Errorf("Issues.ListIssues returned %+v, want %+v", issues, want)
+	}
+}
+
+func TestListProjectIssues(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testURL(t, r, "/api/v4/projects/1/issues?assignee_id=2&author_id=1")
+		fmt.Fprint(w, `[{"id":1, "description": "This is test project", "author" : {"id" : 1, "name": "snehal"}, "assignees":[{"id":1}]}]`)
+	})
+
+	listProjectIssue := &ListProjectIssuesOptions{
+		AuthorID:   Int(01),
+		AssigneeID: Int(02),
+	}
+	issues, _, err := client.Issues.ListProjectIssues("1", listProjectIssue)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := []*Issue{{
+		ID:          1,
+		Description: "This is test project",
+		Author:      &IssueAuthor{ID: 1, Name: "snehal"},
+		Assignees:   []*IssueAssignee{{ID: 1}},
+	}}
+
+	if !reflect.DeepEqual(want, issues) {
+		t.Errorf("Issues.ListProjectIssues returned %+v, want %+v", issues, want)
+	}
+}
+
+func TestListGroupIssues(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/groups/1/issues", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testURL(t, r, "/api/v4/groups/1/issues?assignee_id=2&author_id=1&state=Open")
+		fmt.Fprint(w, `[{"id":1, "description": "This is test project", "author" : {"id" : 1, "name": "snehal"}, "assignees":[{"id":1}]}]`)
+	})
+
+	listGroupIssue := &ListGroupIssuesOptions{
+		State:      String("Open"),
+		AuthorID:   Int(01),
+		AssigneeID: Int(02),
+	}
+
+	issues, _, err := client.Issues.ListGroupIssues("1", listGroupIssue)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := []*Issue{{
+		ID:          1,
+		Description: "This is test project",
+		Author:      &IssueAuthor{ID: 1, Name: "snehal"},
+		Assignees:   []*IssueAssignee{{ID: 1}},
+	}}
+
+	if !reflect.DeepEqual(want, issues) {
+		t.Errorf("Issues.ListGroupIssues returned %+v, want %+v", issues, want)
+	}
+}
+
+func TestCreateIssue(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		fmt.Fprint(w, `{"id":1, "title" : "Title of issue", "description": "This is description of an issue", "author" : {"id" : 1, "name": "snehal"}, "assignees":[{"id":1}]}`)
+	})
+
+	createIssueOptions := &CreateIssueOptions{
+		Title:       String("Title of issue"),
+		Description: String("This is description of an issue"),
+	}
+
+	issue, _, err := client.Issues.CreateIssue("1", createIssueOptions)
+
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := &Issue{
+		ID:          1,
+		Title:       "Title of issue",
+		Description: "This is description of an issue",
+		Author:      &IssueAuthor{ID: 1, Name: "snehal"},
+		Assignees:   []*IssueAssignee{{ID: 1}},
+	}
+
+	if !reflect.DeepEqual(want, issue) {
+		t.Errorf("Issues.CreateIssue returned %+v, want %+v", issue, want)
+	}
+}
+
+func TestUpdateIssue(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "PUT")
+		fmt.Fprint(w, `{"id":1, "title" : "Title of issue", "description": "This is description of an issue", "author" : {"id" : 1, "name": "snehal"}, "assignees":[{"id":1}]}`)
+	})
+
+	updateIssueOpt := &UpdateIssueOptions{
+		Title:       String("Title of issue"),
+		Description: String("This is description of an issue"),
+	}
+	issue, _, err := client.Issues.UpdateIssue(1, 5, updateIssueOpt)
+
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := &Issue{
+		ID:          1,
+		Title:       "Title of issue",
+		Description: "This is description of an issue",
+		Author:      &IssueAuthor{ID: 1, Name: "snehal"},
+		Assignees:   []*IssueAssignee{{ID: 1}},
+	}
+
+	if !reflect.DeepEqual(want, issue) {
+		t.Errorf("Issues.UpdateIssue returned %+v, want %+v", issue, want)
+	}
+}
+
+func TestSubscribeToIssue(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5/subscribe", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		fmt.Fprint(w, `{"id":1, "title" : "Title of issue", "description": "This is description of an issue", "author" : {"id" : 1, "name": "snehal"}, "assignees":[{"id":1}]}`)
+	})
+
+	issue, _, err := client.Issues.SubscribeToIssue("1", 5)
+
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := &Issue{
+		ID:          1,
+		Title:       "Title of issue",
+		Description: "This is description of an issue",
+		Author:      &IssueAuthor{ID: 1, Name: "snehal"},
+		Assignees:   []*IssueAssignee{{ID: 1}},
+	}
+
+	if !reflect.DeepEqual(want, issue) {
+		t.Errorf("Issues.SubscribeToIssue returned %+v, want %+v", issue, want)
+	}
+}
+
+func TestUnsubscribeFromIssue(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5/unsubscribe", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		fmt.Fprint(w, `{"id":1, "title" : "Title of issue", "description": "This is description of an issue", "author" : {"id" : 1, "name": "snehal"}, "assignees":[{"id":1}]}`)
+	})
+
+	issue, _, err := client.Issues.UnsubscribeFromIssue("1", 5)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := &Issue{
+		ID:          1,
+		Title:       "Title of issue",
+		Description: "This is description of an issue",
+		Author:      &IssueAuthor{ID: 1, Name: "snehal"},
+		Assignees:   []*IssueAssignee{{ID: 1}},
+	}
+
+	if !reflect.DeepEqual(want, issue) {
+		t.Errorf("Issues.UnsubscribeFromIssue returned %+v, want %+v", issue, want)
+	}
+}
+
+func TestListMergeRequestsClosingIssue(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5/closed_by", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `[{"id":1, "title" : "test merge one"},{"id":2, "title" : "test merge two"}]`)
+	})
+
+	listMergeRequestsClosingIssueOpt := &ListMergeRequestsClosingIssueOptions{
+		Page:    1,
+		PerPage: 10,
+	}
+	mergeRequest, _, err := client.Issues.ListMergeRequestsClosingIssue("1", 5, listMergeRequestsClosingIssueOpt)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := []*MergeRequest{{ID: 1, Title: "test merge one"}, {ID: 2, Title: "test merge two"}}
+
+	if !reflect.DeepEqual(want, mergeRequest) {
+		t.Errorf("Issues.ListMergeRequestsClosingIssue returned %+v, want %+v", mergeRequest, want)
+	}
+}
+
+func TestSetTimeEstimate(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5/time_estimate", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		fmt.Fprint(w, `{"human_time_estimate": "3h 30m", "human_total_time_spent": null, "time_estimate": 12600, "total_time_spent": 0}`)
+	})
+
+	setTimeEstiOpt := &SetTimeEstimateOptions{
+		Duration: String("3h 30m"),
+	}
+
+	timeState, _, err := client.Issues.SetTimeEstimate("1", 5, setTimeEstiOpt)
+	if err != nil {
+		log.Fatal(err)
+	}
+	want := &TimeStats{HumanTimeEstimate: "3h 30m", HumanTotalTimeSpent: "", TimeEstimate: 12600, TotalTimeSpent: 0}
+
+	if !reflect.DeepEqual(want, timeState) {
+		t.Errorf("Issues.SetTimeEstimate returned %+v, want %+v", timeState, want)
+	}
+}
+
+func TestResetTimeEstimate(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5/reset_time_estimate", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		fmt.Fprint(w, `{"human_time_estimate": null, "human_total_time_spent": null, "time_estimate": 0, "total_time_spent": 0}`)
+	})
+
+	timeState, _, err := client.Issues.ResetTimeEstimate("1", 5)
+	if err != nil {
+		log.Fatal(err)
+	}
+	want := &TimeStats{HumanTimeEstimate: "", HumanTotalTimeSpent: "", TimeEstimate: 0, TotalTimeSpent: 0}
+
+	if !reflect.DeepEqual(want, timeState) {
+		t.Errorf("Issues.ResetTimeEstimate returned %+v, want %+v", timeState, want)
+	}
+}
+
+func TestAddSpentTime(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5/add_spent_time", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		testURL(t, r, "/api/v4/projects/1/issues/5/add_spent_time")
+		fmt.Fprint(w, `{"human_time_estimate": null, "human_total_time_spent": "1h", "time_estimate": 0, "total_time_spent": 3600}`)
+	})
+	addSpentTimeOpt := &AddSpentTimeOptions{
+		Duration: String("1h"),
+	}
+
+	timeState, _, err := client.Issues.AddSpentTime("1", 5, addSpentTimeOpt)
+	if err != nil {
+		log.Fatal(err)
+	}
+	want := &TimeStats{HumanTimeEstimate: "", HumanTotalTimeSpent: "1h", TimeEstimate: 0, TotalTimeSpent: 3600}
+
+	if !reflect.DeepEqual(want, timeState) {
+		t.Errorf("Issues.AddSpentTime returned %+v, want %+v", timeState, want)
+	}
+}
+
+func TestResetSpentTime(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5/reset_spent_time", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		testURL(t, r, "/api/v4/projects/1/issues/5/reset_spent_time")
+		fmt.Fprint(w, `{"human_time_estimate": null, "human_total_time_spent": "", "time_estimate": 0, "total_time_spent": 0}`)
+	})
+
+	timeState, _, err := client.Issues.ResetSpentTime("1", 5)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := &TimeStats{HumanTimeEstimate: "", HumanTotalTimeSpent: "", TimeEstimate: 0, TotalTimeSpent: 0}
+	if !reflect.DeepEqual(want, timeState) {
+		t.Errorf("Issues.ResetSpentTime returned %+v, want %+v", timeState, want)
+	}
+}
+
+func TestGetTimeSpent(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/issues/5/time_stats", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testURL(t, r, "/api/v4/projects/1/issues/5/time_stats")
+		fmt.Fprint(w, `{"human_time_estimate": "2h", "human_total_time_spent": "1h", "time_estimate": 7200, "total_time_spent": 3600}`)
+	})
+
+	timeState, _, err := client.Issues.GetTimeSpent("1", 5)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	want := &TimeStats{HumanTimeEstimate: "2h", HumanTotalTimeSpent: "1h", TimeEstimate: 7200, TotalTimeSpent: 3600}
+	if !reflect.DeepEqual(want, timeState) {
+		t.Errorf("Issues.GetTimeSpent returned %+v, want %+v", timeState, want)
+	}
+}
diff --git a/labels_test.go b/labels_test.go
index 4982a82..014b9a2 100644
--- a/labels_test.go
+++ b/labels_test.go
@@ -27,7 +27,7 @@ func TestCreateLabel(t *testing.T) {
 	if err != nil {
 		log.Fatal(err)
 	}
-	want := &Label{ID:1, Name:"My Label", Color:"#11FF22"}
+	want := &Label{ID: 1, Name: "My Label", Color: "#11FF22"}
 	if !reflect.DeepEqual(want, label) {
 		t.Errorf("Labels.CreateLabel returned %+v, want %+v", label, want)
 	}
@@ -64,13 +64,13 @@ func TestUpdateLabel(t *testing.T) {
 
 	// Update label
 	l := &UpdateLabelOptions{
-		Name : String("My Label"),
-		NewName : String("New Label"),
-		Color : String("#11FF23"),
-		Description : String("This is updated label"),
+		Name:        String("My Label"),
+		NewName:     String("New Label"),
+		Color:       String("#11FF23"),
+		Description: String("This is updated label"),
 	}
 
-	label, resp , err := client.Labels.UpdateLabel("1", l)
+	label, resp, err := client.Labels.UpdateLabel("1", l)
 
 	if resp == nil {
 		log.Fatal(err)
@@ -79,14 +79,14 @@ func TestUpdateLabel(t *testing.T) {
 		log.Fatal(err)
 	}
 
-	want := &Label{ID:1, Name:"New Label", Color:"#11FF23", Description:"This is updated label"}
+	want := &Label{ID: 1, Name: "New Label", Color: "#11FF23", Description: "This is updated label"}
 
 	if !reflect.DeepEqual(want, label) {
 		t.Errorf("Labels.UpdateLabel returned %+v, want %+v", label, want)
 	}
 }
 
-func TestSubscribeToLabel(t *testing.T)  {
+func TestSubscribeToLabel(t *testing.T) {
 	mux, server, client := setup()
 	defer teardown(server)
 
@@ -95,17 +95,17 @@ func TestSubscribeToLabel(t *testing.T)  {
 		fmt.Fprint(w, `{  "id" : 5, "name" : "bug", "color" : "#d9534f", "description": "Bug reported by user", "open_issues_count": 1, "closed_issues_count": 0, "open_merge_requests_count": 1, "subscribed": true,"priority": null}`)
 	})
 
-	label, _ , err := client.Labels.SubscribeToLabel("1", "5")
+	label, _, err := client.Labels.SubscribeToLabel("1", "5")
 	if err != nil {
 		log.Fatal(err)
 	}
-	want := &Label{ID:5, Name:"bug", Color:"#d9534f", Description:"Bug reported by user", OpenIssuesCount:1, ClosedIssuesCount:0, OpenMergeRequestsCount:1, Subscribed: true}
+	want := &Label{ID: 5, Name: "bug", Color: "#d9534f", Description: "Bug reported by user", OpenIssuesCount: 1, ClosedIssuesCount: 0, OpenMergeRequestsCount: 1, Subscribed: true}
 	if !reflect.DeepEqual(want, label) {
-		t.Errorf("Labels.UpdateLabel returned %+v, want %+v", label, want)
+		t.Errorf("Labels.SubscribeToLabel returned %+v, want %+v", label, want)
 	}
 }
 
-func TestUnsubscribeFromLabel(t *testing.T)  {
+func TestUnsubscribeFromLabel(t *testing.T) {
 	mux, server, client := setup()
 	defer teardown(server)
 
@@ -113,7 +113,7 @@ func TestUnsubscribeFromLabel(t *testing.T)  {
 		testMethod(t, r, "POST")
 	})
 
-	_ , err := client.Labels.UnsubscribeFromLabel("1", "5")
+	_, err := client.Labels.UnsubscribeFromLabel("1", "5")
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -128,17 +128,17 @@ func TestListLabels(t *testing.T) {
 		fmt.Fprint(w, `[{  "id" : 5, "name" : "bug", "color" : "#d9534f", "description": "Bug reported by user", "open_issues_count": 1, "closed_issues_count": 0, "open_merge_requests_count": 1, "subscribed": true,"priority": null}]`)
 	})
 
-	o := &ListLabelsOptions {
-		Page:1,
-		PerPage:10,
+	o := &ListLabelsOptions{
+		Page:    1,
+		PerPage: 10,
 	}
-	label, _ , err := client.Labels.ListLabels("1", o)
+	label, _, err := client.Labels.ListLabels("1", o)
 	if err != nil {
 		t.Log(err.Error() == "invalid ID type 1.1, the ID must be an int or a string")
 
 	}
-	want := []*Label{{ID:5, Name:"bug", Color:"#d9534f", Description:"Bug reported by user", OpenIssuesCount:1, ClosedIssuesCount:0, OpenMergeRequestsCount:1, Subscribed: true}}
+	want := []*Label{{ID: 5, Name: "bug", Color: "#d9534f", Description: "Bug reported by user", OpenIssuesCount: 1, ClosedIssuesCount: 0, OpenMergeRequestsCount: 1, Subscribed: true}}
 	if !reflect.DeepEqual(want, label) {
-		t.Errorf("Labels.UpdateLabel returned %+v, want %+v", label, want)
+		t.Errorf("Labels.ListLabels returned %+v, want %+v", label, want)
 	}
-}
\ No newline at end of file
+}
diff --git a/settings_test.go b/settings_test.go
new file mode 100644
index 0000000..c3d320e
--- /dev/null
+++ b/settings_test.go
@@ -0,0 +1,51 @@
+package gitlab
+
+import (
+	"fmt"
+	"net/http"
+	"reflect"
+	"testing"
+)
+
+func TestGetSettings(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/application/settings", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{"id":1,    "default_projects_limit" : 100000}`)
+	})
+
+	settings, _, err := client.Settings.GetSettings()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &Settings{ID: 1, DefaultProjectsLimit: 100000}
+	if !reflect.DeepEqual(settings, want) {
+		t.Errorf("Settings.GetSettings returned %+v, want %+v", settings, want)
+	}
+}
+
+func TestUpdateSettings(t *testing.T) {
+	mux, server, client := setup()
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/application/settings", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "PUT")
+		fmt.Fprint(w, `{"default_projects_limit" : 100}`)
+	})
+
+	options := &UpdateSettingsOptions{
+		DefaultProjectsLimit: Int(100),
+	}
+	settings, _, err := client.Settings.UpdateSettings(options)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := &Settings{DefaultProjectsLimit: 100}
+	if !reflect.DeepEqual(settings, want) {
+		t.Errorf("Settings.UpdateSettings returned %+v, want %+v", settings, want)
+	}
+}