From 97b759670da442a06e9477f7587674b52f9eecce Mon Sep 17 00:00:00 2001 From: jorge-ferrero-ag Date: Mon, 18 Aug 2025 23:14:19 +0200 Subject: [PATCH 1/9] feat: Add GetClassroom method to ClassroomService Implements the GetClassroom method to retrieve a GitHub Classroom by ID if the user is an administrator. Adds corresponding unit tests to verify correct API interaction and response handling. --- github/classroom.go | 23 ++++++++++++++++ github/classroom_test.go | 57 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/github/classroom.go b/github/classroom.go index 8f6ce14511e..926a60db12c 100644 --- a/github/classroom.go +++ b/github/classroom.go @@ -80,3 +80,26 @@ func (s *ClassroomService) GetAssignment(ctx context.Context, assignmentID int64 return assignment, resp, nil } + +// GetClassroom gets a GitHub Classroom classroom for the current user. Classroom will only be +// returned if the current user is an administrator of the GitHub Classroom. +// +// GitHub API docs: https://docs.github.com/rest/classroom/classroom#get-a-classroom +// +//meta:operation GET /classrooms/{classroom_id} +func (s *ClassroomService) GetClassroom(ctx context.Context, classroomID int64) (*Classroom, *Response, error) { + u := fmt.Sprintf("classrooms/%v", classroomID) + + req, err := s.client.NewRequest(http.MethodGet, u, nil) + if err != nil { + return nil, nil, err + } + + classroom := new(Classroom) + resp, err := s.client.Do(ctx, req, classroom) + if err != nil { + return nil, resp, err + } + + return classroom, resp, nil +} diff --git a/github/classroom_test.go b/github/classroom_test.go index a6c67f15180..4c1fe40e76b 100644 --- a/github/classroom_test.go +++ b/github/classroom_test.go @@ -209,3 +209,60 @@ func TestClassroomService_GetAssignment(t *testing.T) { return resp, err }) } + +func TestClassroomService_GetClassroom(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/classrooms/1296269", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "id": 1296269, + "name": "Programming Elixir", + "archived": false, + "organization": { + "id": 1, + "login": "programming-elixir", + "node_id": "MDEyOk9yZ2FuaXphdGlvbjE=", + "html_url": "https://github.com/programming-elixir", + "name": "Learn how to build fault tolerant applications", + "avatar_url": "https://avatars.githubusercontent.com/u/9919?v=4" + }, + "url": "https://classroom.github.com/classrooms/1-programming-elixir" + }`) + }) + + ctx := context.Background() + classroom, _, err := client.Classroom.GetClassroom(ctx, 1296269) + if err != nil { + t.Errorf("Classroom.GetClassroom returned error: %v", err) + } + + want := &Classroom{ + ID: Ptr(int64(1296269)), + Name: Ptr("Programming Elixir"), + Archived: Ptr(false), + Organization: &Organization{ + ID: Ptr(int64(1)), + Login: Ptr("programming-elixir"), + NodeID: Ptr("MDEyOk9yZ2FuaXphdGlvbjE="), + HTMLURL: Ptr("https://github.com/programming-elixir"), + Name: Ptr("Learn how to build fault tolerant applications"), + AvatarURL: Ptr("https://avatars.githubusercontent.com/u/9919?v=4"), + }, + URL: Ptr("https://classroom.github.com/classrooms/1-programming-elixir"), + } + + if !cmp.Equal(classroom, want) { + t.Errorf("Classroom.GetClassroom returned %+v, want %+v", classroom, want) + } + + const methodName = "GetClassroom" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Classroom.GetClassroom(ctx, 1296269) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From a6efddf0667318315e571e52171100b3562e6910 Mon Sep 17 00:00:00 2001 From: jorge-ferrero-ag Date: Mon, 18 Aug 2025 23:18:35 +0200 Subject: [PATCH 2/9] Replace reflect.Ptr with reflect.Pointer in addOptions Updated the addOptions function to use reflect.Pointer instead of the deprecated reflect.Ptr for checking pointer kinds. This change ensures compatibility with newer Go versions. --- github/github.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/github.go b/github/github.go index b1e7b3ddaf1..2edc9cc49c1 100644 --- a/github/github.go +++ b/github/github.go @@ -309,7 +309,7 @@ type RawOptions struct { // must be a struct whose fields may contain "url" tags. func addOptions(s string, opts any) (string, error) { v := reflect.ValueOf(opts) - if v.Kind() == reflect.Ptr && v.IsNil() { + if v.Kind() == reflect.Pointer && v.IsNil() { return s, nil } From 4a35fd3ce2475878590e0bda324203ac9853d52e Mon Sep 17 00:00:00 2001 From: jorge-ferrero-ag Date: Mon, 18 Aug 2025 23:23:34 +0200 Subject: [PATCH 3/9] Add ListClassrooms method to ClassroomService Implements the ListClassrooms method to retrieve classrooms for the current user via the GitHub API. Adds corresponding tests to verify correct API interaction and response parsing. --- github/classroom.go | 26 +++++++++++++++++ github/classroom_test.go | 63 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/github/classroom.go b/github/classroom.go index 926a60db12c..2637857f493 100644 --- a/github/classroom.go +++ b/github/classroom.go @@ -103,3 +103,29 @@ func (s *ClassroomService) GetClassroom(ctx context.Context, classroomID int64) return classroom, resp, nil } + +// ListClassrooms lists GitHub Classroom classrooms for the current user. Classrooms will only be +// returned if the current user is an administrator of one or more GitHub Classrooms. +// +// GitHub API docs: https://docs.github.com/rest/classroom/classroom#list-classrooms +// +//meta:operation GET /classrooms +func (s *ClassroomService) ListClassrooms(ctx context.Context, opts *ListOptions) ([]*Classroom, *Response, error) { + u, err := addOptions("classrooms", opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(http.MethodGet, u, nil) + if err != nil { + return nil, nil, err + } + + var classrooms []*Classroom + resp, err := s.client.Do(ctx, req, &classrooms) + if err != nil { + return nil, resp, err + } + + return classrooms, resp, nil +} diff --git a/github/classroom_test.go b/github/classroom_test.go index 4c1fe40e76b..67d51ddf5eb 100644 --- a/github/classroom_test.go +++ b/github/classroom_test.go @@ -120,7 +120,7 @@ func TestClassroomService_GetAssignment(t *testing.T) { client, mux, _ := setup(t) mux.HandleFunc("/assignments/12", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") + testMethod(t, r, http.MethodGet) fmt.Fprint(w, `{ "id": 12, "public_repo": false, @@ -215,7 +215,7 @@ func TestClassroomService_GetClassroom(t *testing.T) { client, mux, _ := setup(t) mux.HandleFunc("/classrooms/1296269", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "GET") + testMethod(t, r, http.MethodGet) fmt.Fprint(w, `{ "id": 1296269, "name": "Programming Elixir", @@ -266,3 +266,62 @@ func TestClassroomService_GetClassroom(t *testing.T) { return resp, err }) } + +func TestClassroomService_ListClassrooms(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/classrooms", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + testFormValues(t, r, values{"page": "2", "per_page": "2"}) + fmt.Fprint(w, `[ + { + "id": 1296269, + "name": "Programming Elixir", + "archived": false, + "url": "https://classroom.github.com/classrooms/1-programming-elixir" + }, + { + "id": 1296270, + "name": "Advanced Programming", + "archived": true, + "url": "https://classroom.github.com/classrooms/2-advanced-programming" + } + ]`) + }) + + opt := &ListOptions{Page: 2, PerPage: 2} + ctx := context.Background() + classrooms, _, err := client.Classroom.ListClassrooms(ctx, opt) + if err != nil { + t.Errorf("Classroom.ListClassrooms returned error: %v", err) + } + + want := []*Classroom{ + { + ID: Ptr(int64(1296269)), + Name: Ptr("Programming Elixir"), + Archived: Ptr(false), + URL: Ptr("https://classroom.github.com/classrooms/1-programming-elixir"), + }, + { + ID: Ptr(int64(1296270)), + Name: Ptr("Advanced Programming"), + Archived: Ptr(true), + URL: Ptr("https://classroom.github.com/classrooms/2-advanced-programming"), + }, + } + + if !cmp.Equal(classrooms, want) { + t.Errorf("Classroom.ListClassrooms returned %+v, want %+v", classrooms, want) + } + + const methodName = "ListClassrooms" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Classroom.ListClassrooms(ctx, opt) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From af27910ca30f43b4b9b691185569f3de89d63de8 Mon Sep 17 00:00:00 2001 From: jorge-ferrero-ag Date: Mon, 18 Aug 2025 23:32:50 +0200 Subject: [PATCH 4/9] Add ListClassroomAssignments to ClassroomService Implements the ListClassroomAssignments method to fetch assignments for a classroom via the GitHub API. Includes comprehensive tests for the new method, covering normal operation and error handling. --- github/classroom.go | 27 ++++++++ github/classroom_test.go | 135 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) diff --git a/github/classroom.go b/github/classroom.go index 2637857f493..4b6e0b1047e 100644 --- a/github/classroom.go +++ b/github/classroom.go @@ -129,3 +129,30 @@ func (s *ClassroomService) ListClassrooms(ctx context.Context, opts *ListOptions return classrooms, resp, nil } + +// ListClassroomAssignments lists GitHub Classroom assignments for a classroom. Assignments will only be +// returned if the current user is an administrator of the GitHub Classroom. +// +// GitHub API docs: https://docs.github.com/rest/classroom/classroom#list-assignments-for-a-classroom +// +//meta:operation GET /classrooms/{classroom_id}/assignments +func (s *ClassroomService) ListClassroomAssignments(ctx context.Context, classroomID int64, opts *ListOptions) ([]*ClassroomAssignment, *Response, error) { + u := fmt.Sprintf("classrooms/%v/assignments", classroomID) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest(http.MethodGet, u, nil) + if err != nil { + return nil, nil, err + } + + var assignments []*ClassroomAssignment + resp, err := s.client.Do(ctx, req, &assignments) + if err != nil { + return nil, resp, err + } + + return assignments, resp, nil +} diff --git a/github/classroom_test.go b/github/classroom_test.go index 67d51ddf5eb..ee7a478cf91 100644 --- a/github/classroom_test.go +++ b/github/classroom_test.go @@ -325,3 +325,138 @@ func TestClassroomService_ListClassrooms(t *testing.T) { return resp, err }) } + +func TestClassroomService_ListClassroomAssignments(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/classrooms/1296269/assignments", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, http.MethodGet) + testFormValues(t, r, values{"page": "2", "per_page": "2"}) + fmt.Fprint(w, `[ + { + "id": 12, + "public_repo": false, + "title": "Intro to Binaries", + "type": "individual", + "invite_link": "https://classroom.github.com/a/Lx7jiUgx", + "invitations_enabled": true, + "slug": "intro-to-binaries", + "students_are_repo_admins": false, + "feedback_pull_requests_enabled": true, + "max_teams": 0, + "max_members": 0, + "editor": "codespaces", + "accepted": 100, + "submitted": 40, + "passing": 10, + "language": "ruby", + "deadline": "2011-01-26T19:06:43Z", + "classroom": { + "id": 1296269, + "name": "Programming Elixir", + "archived": false, + "url": "https://classroom.github.com/classrooms/1-programming-elixir" + } + }, + { + "id": 13, + "public_repo": true, + "title": "Advanced Programming", + "type": "group", + "invite_link": "https://classroom.github.com/a/AdvancedProg", + "invitations_enabled": true, + "slug": "advanced-programming", + "students_are_repo_admins": true, + "feedback_pull_requests_enabled": false, + "max_teams": 5, + "max_members": 3, + "editor": "vscode", + "accepted": 50, + "submitted": 25, + "passing": 20, + "language": "python", + "deadline": "2020-01-11T11:59:22Z", + "classroom": { + "id": 1296269, + "name": "Programming Elixir", + "archived": false, + "url": "https://classroom.github.com/classrooms/1-programming-elixir" + } + } + ]`) + }) + + opt := &ListOptions{Page: 2, PerPage: 2} + ctx := context.Background() + assignments, _, err := client.Classroom.ListClassroomAssignments(ctx, 1296269, opt) + if err != nil { + t.Errorf("Classroom.ListClassroomAssignments returned error: %v", err) + } + + want := []*ClassroomAssignment{ + { + ID: Ptr(int64(12)), + PublicRepo: Ptr(false), + Title: Ptr("Intro to Binaries"), + Type: Ptr("individual"), + InviteLink: Ptr("https://classroom.github.com/a/Lx7jiUgx"), + InvitationsEnabled: Ptr(true), + Slug: Ptr("intro-to-binaries"), + StudentsAreRepoAdmins: Ptr(false), + FeedbackPullRequestsEnabled: Ptr(true), + MaxTeams: Ptr(0), + MaxMembers: Ptr(0), + Editor: Ptr("codespaces"), + Accepted: Ptr(100), + Submitted: Ptr(40), + Passing: Ptr(10), + Language: Ptr("ruby"), + Deadline: func() *Timestamp { t, _ := time.Parse(time.RFC3339, "2011-01-26T19:06:43Z"); return &Timestamp{t} }(), + Classroom: &Classroom{ + ID: Ptr(int64(1296269)), + Name: Ptr("Programming Elixir"), + Archived: Ptr(false), + URL: Ptr("https://classroom.github.com/classrooms/1-programming-elixir"), + }, + }, + { + ID: Ptr(int64(13)), + PublicRepo: Ptr(true), + Title: Ptr("Advanced Programming"), + Type: Ptr("group"), + InviteLink: Ptr("https://classroom.github.com/a/AdvancedProg"), + InvitationsEnabled: Ptr(true), + Slug: Ptr("advanced-programming"), + StudentsAreRepoAdmins: Ptr(true), + FeedbackPullRequestsEnabled: Ptr(false), + MaxTeams: Ptr(5), + MaxMembers: Ptr(3), + Editor: Ptr("vscode"), + Accepted: Ptr(50), + Submitted: Ptr(25), + Passing: Ptr(20), + Language: Ptr("python"), + Deadline: func() *Timestamp { t, _ := time.Parse(time.RFC3339, "2020-01-11T11:59:22Z"); return &Timestamp{t} }(), + Classroom: &Classroom{ + ID: Ptr(int64(1296269)), + Name: Ptr("Programming Elixir"), + Archived: Ptr(false), + URL: Ptr("https://classroom.github.com/classrooms/1-programming-elixir"), + }, + }, + } + + if !cmp.Equal(assignments, want) { + t.Errorf("Classroom.ListClassroomAssignments returned %+v, want %+v", assignments, want) + } + + const methodName = "ListClassroomAssignments" + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Classroom.ListClassroomAssignments(ctx, 1296269, opt) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From e8ca02460b8dc037714e4c1a45cb63f3c8bd177f Mon Sep 17 00:00:00 2001 From: jorge-ferrero-ag Date: Tue, 19 Aug 2025 10:04:29 +0200 Subject: [PATCH 5/9] Replace reflect.Ptr with reflect.Pointer in stringifyValue Updated the usage of reflect.Ptr to reflect.Pointer in the stringifyValue function to align with the latest Go reflect package conventions. --- github/strings.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github/strings.go b/github/strings.go index 46fd55ad142..10322301261 100644 --- a/github/strings.go +++ b/github/strings.go @@ -26,7 +26,7 @@ func Stringify(message any) string { // stringifyValue was heavily inspired by the goprotobuf library. func stringifyValue(w *bytes.Buffer, val reflect.Value) { - if val.Kind() == reflect.Ptr && val.IsNil() { + if val.Kind() == reflect.Pointer && val.IsNil() { w.WriteString("") return } @@ -64,7 +64,7 @@ func stringifyValue(w *bytes.Buffer, val reflect.Value) { var sep bool for i := 0; i < v.NumField(); i++ { fv := v.Field(i) - if fv.Kind() == reflect.Ptr && fv.IsNil() { + if fv.Kind() == reflect.Pointer && fv.IsNil() { continue } if fv.Kind() == reflect.Slice && fv.IsNil() { From ecc632b89dff1980a8f24deaf5f3a90fa1c92b98 Mon Sep 17 00:00:00 2001 From: jorge-ferrero-ag Date: Thu, 21 Aug 2025 09:36:57 +0200 Subject: [PATCH 6/9] Replace http.MethodGet with "GET" string in classroom Replaces usage of http.MethodGet with the string literal "GET" in both the ClassroomService methods and their corresponding tests. Also removes the unused net/http import. --- github/classroom.go | 9 ++++----- github/classroom_test.go | 8 ++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/github/classroom.go b/github/classroom.go index 4b6e0b1047e..2c7e3a1d71d 100644 --- a/github/classroom.go +++ b/github/classroom.go @@ -8,7 +8,6 @@ package github import ( "context" "fmt" - "net/http" ) // ClassroomService handles communication with the GitHub Classroom related @@ -67,7 +66,7 @@ func (a ClassroomAssignment) String() string { func (s *ClassroomService) GetAssignment(ctx context.Context, assignmentID int64) (*ClassroomAssignment, *Response, error) { u := fmt.Sprintf("assignments/%v", assignmentID) - req, err := s.client.NewRequest(http.MethodGet, u, nil) + req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err } @@ -90,7 +89,7 @@ func (s *ClassroomService) GetAssignment(ctx context.Context, assignmentID int64 func (s *ClassroomService) GetClassroom(ctx context.Context, classroomID int64) (*Classroom, *Response, error) { u := fmt.Sprintf("classrooms/%v", classroomID) - req, err := s.client.NewRequest(http.MethodGet, u, nil) + req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err } @@ -116,7 +115,7 @@ func (s *ClassroomService) ListClassrooms(ctx context.Context, opts *ListOptions return nil, nil, err } - req, err := s.client.NewRequest(http.MethodGet, u, nil) + req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err } @@ -143,7 +142,7 @@ func (s *ClassroomService) ListClassroomAssignments(ctx context.Context, classro return nil, nil, err } - req, err := s.client.NewRequest(http.MethodGet, u, nil) + req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err } diff --git a/github/classroom_test.go b/github/classroom_test.go index ee7a478cf91..7b91d9fae61 100644 --- a/github/classroom_test.go +++ b/github/classroom_test.go @@ -120,7 +120,7 @@ func TestClassroomService_GetAssignment(t *testing.T) { client, mux, _ := setup(t) mux.HandleFunc("/assignments/12", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodGet) + testMethod(t, r, "GET") fmt.Fprint(w, `{ "id": 12, "public_repo": false, @@ -215,7 +215,7 @@ func TestClassroomService_GetClassroom(t *testing.T) { client, mux, _ := setup(t) mux.HandleFunc("/classrooms/1296269", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodGet) + testMethod(t, r, "GET") fmt.Fprint(w, `{ "id": 1296269, "name": "Programming Elixir", @@ -272,7 +272,7 @@ func TestClassroomService_ListClassrooms(t *testing.T) { client, mux, _ := setup(t) mux.HandleFunc("/classrooms", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodGet) + testMethod(t, r, "GET") testFormValues(t, r, values{"page": "2", "per_page": "2"}) fmt.Fprint(w, `[ { @@ -331,7 +331,7 @@ func TestClassroomService_ListClassroomAssignments(t *testing.T) { client, mux, _ := setup(t) mux.HandleFunc("/classrooms/1296269/assignments", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodGet) + testMethod(t, r, "GET") testFormValues(t, r, values{"page": "2", "per_page": "2"}) fmt.Fprint(w, `[ { From cc627ddf3d81772a5ef4146e2b803b9900c33199 Mon Sep 17 00:00:00 2001 From: jferrl Date: Tue, 23 Sep 2025 09:11:55 +0200 Subject: [PATCH 7/9] chore: Update comments for Classroom service methods Revised comments in classroom.go to clarify method descriptions and improve wording for GetClassroom and ListClassrooms functions. --- github/classroom.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github/classroom.go b/github/classroom.go index 2c7e3a1d71d..5c44cc0d406 100644 --- a/github/classroom.go +++ b/github/classroom.go @@ -80,7 +80,7 @@ func (s *ClassroomService) GetAssignment(ctx context.Context, assignmentID int64 return assignment, resp, nil } -// GetClassroom gets a GitHub Classroom classroom for the current user. Classroom will only be +// GetClassroom gets a GitHub Classroom for the current user. Classroom will only be // returned if the current user is an administrator of the GitHub Classroom. // // GitHub API docs: https://docs.github.com/rest/classroom/classroom#get-a-classroom @@ -103,7 +103,7 @@ func (s *ClassroomService) GetClassroom(ctx context.Context, classroomID int64) return classroom, resp, nil } -// ListClassrooms lists GitHub Classroom classrooms for the current user. Classrooms will only be +// ListClassrooms lists GitHub Classrooms for the current user. Classrooms will only be // returned if the current user is an administrator of one or more GitHub Classrooms. // // GitHub API docs: https://docs.github.com/rest/classroom/classroom#list-classrooms From e3fd949ecff8c6635eba0ba54412b4f2b310c0ec Mon Sep 17 00:00:00 2001 From: jferrl Date: Tue, 23 Sep 2025 09:12:18 +0200 Subject: [PATCH 8/9] Update test URLs to use example.com Replaces GitHub and GitHub Classroom URLs with example.com in classroom and assignment test cases for consistency and to avoid referencing real endpoints. --- github/classroom_test.go | 64 ++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/github/classroom_test.go b/github/classroom_test.go index 7b91d9fae61..c53af2cab00 100644 --- a/github/classroom_test.go +++ b/github/classroom_test.go @@ -27,11 +27,11 @@ func TestClassroom_Marshal(t *testing.T) { ID: Ptr(int64(1)), Login: Ptr("programming-elixir"), NodeID: Ptr("MDEyOk9yZ2FuaXphdGlvbjE="), - HTMLURL: Ptr("https://github.com/programming-elixir"), + HTMLURL: Ptr("https://example.com/programming-elixir"), Name: Ptr("Learn how to build fault tolerant applications"), - AvatarURL: Ptr("https://avatars.githubusercontent.com/u/9919?v=4"), + AvatarURL: Ptr("https://example.com/avatars/u/9919?v=4"), }, - URL: Ptr("https://classroom.github.com/classrooms/1-programming-elixir"), + URL: Ptr("https://example.com/classrooms/programming"), } want := `{ @@ -42,11 +42,11 @@ func TestClassroom_Marshal(t *testing.T) { "id": 1, "login": "programming-elixir", "node_id": "MDEyOk9yZ2FuaXphdGlvbjE=", - "html_url": "https://github.com/programming-elixir", + "html_url": "https://example.com/programming-elixir", "name": "Learn how to build fault tolerant applications", - "avatar_url": "https://avatars.githubusercontent.com/u/9919?v=4" + "avatar_url": "https://example.com/avatars/u/9919?v=4" }, - "url": "https://classroom.github.com/classrooms/1-programming-elixir" + "url": "https://example.com/classrooms/programming" }` testJSONMarshal(t, c, want) @@ -61,7 +61,7 @@ func TestClassroomAssignment_Marshal(t *testing.T) { PublicRepo: Ptr(false), Title: Ptr("Intro to Binaries"), Type: Ptr("individual"), - InviteLink: Ptr("https://classroom.github.com/a/Lx7jiUgx"), + InviteLink: Ptr("https://example.com/a/Lx7jiUgx"), InvitationsEnabled: Ptr(true), Slug: Ptr("intro-to-binaries"), StudentsAreRepoAdmins: Ptr(false), @@ -89,7 +89,7 @@ func TestClassroomAssignment_Marshal(t *testing.T) { "public_repo": false, "title": "Intro to Binaries", "type": "individual", - "invite_link": "https://classroom.github.com/a/Lx7jiUgx", + "invite_link": "https://example.com/a/Lx7jiUgx", "invitations_enabled": true, "slug": "intro-to-binaries", "students_are_repo_admins": false, @@ -126,7 +126,7 @@ func TestClassroomService_GetAssignment(t *testing.T) { "public_repo": false, "title": "Intro to Binaries", "type": "individual", - "invite_link": "https://classroom.github.com/a/Lx7jiUgx", + "invite_link": "https://example.com/a/Lx7jiUgx", "invitations_enabled": true, "slug": "intro-to-binaries", "students_are_repo_admins": false, @@ -142,7 +142,7 @@ func TestClassroomService_GetAssignment(t *testing.T) { "starter_code_repository": { "id": 1296269, "full_name": "octocat/Hello-World", - "html_url": "https://github.com/octocat/Hello-World", + "html_url": "https://example.com/octocat/Hello-World", "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "private": false, "default_branch": "main" @@ -151,7 +151,7 @@ func TestClassroomService_GetAssignment(t *testing.T) { "id": 1296269, "name": "Programming Elixir", "archived": false, - "url": "https://classroom.github.com/classrooms/1-programming-elixir" + "url": "https://example.com/classrooms/programming" } }`) }) @@ -167,7 +167,7 @@ func TestClassroomService_GetAssignment(t *testing.T) { PublicRepo: Ptr(false), Title: Ptr("Intro to Binaries"), Type: Ptr("individual"), - InviteLink: Ptr("https://classroom.github.com/a/Lx7jiUgx"), + InviteLink: Ptr("https://example.com/a/Lx7jiUgx"), InvitationsEnabled: Ptr(true), Slug: Ptr("intro-to-binaries"), StudentsAreRepoAdmins: Ptr(false), @@ -183,7 +183,7 @@ func TestClassroomService_GetAssignment(t *testing.T) { StarterCodeRepository: &Repository{ ID: Ptr(int64(1296269)), FullName: Ptr("octocat/Hello-World"), - HTMLURL: Ptr("https://github.com/octocat/Hello-World"), + HTMLURL: Ptr("https://example.com/octocat/Hello-World"), NodeID: Ptr("MDEwOlJlcG9zaXRvcnkxMjk2MjY5"), Private: Ptr(false), DefaultBranch: Ptr("main"), @@ -192,7 +192,7 @@ func TestClassroomService_GetAssignment(t *testing.T) { ID: Ptr(int64(1296269)), Name: Ptr("Programming Elixir"), Archived: Ptr(false), - URL: Ptr("https://classroom.github.com/classrooms/1-programming-elixir"), + URL: Ptr("https://example.com/classrooms/programming"), }, } @@ -224,11 +224,11 @@ func TestClassroomService_GetClassroom(t *testing.T) { "id": 1, "login": "programming-elixir", "node_id": "MDEyOk9yZ2FuaXphdGlvbjE=", - "html_url": "https://github.com/programming-elixir", + "html_url": "https://example.com/programming-elixir", "name": "Learn how to build fault tolerant applications", - "avatar_url": "https://avatars.githubusercontent.com/u/9919?v=4" + "avatar_url": "https://example.com/avatars/u/9919?v=4" }, - "url": "https://classroom.github.com/classrooms/1-programming-elixir" + "url": "https://example.com/classrooms/programming" }`) }) @@ -246,11 +246,11 @@ func TestClassroomService_GetClassroom(t *testing.T) { ID: Ptr(int64(1)), Login: Ptr("programming-elixir"), NodeID: Ptr("MDEyOk9yZ2FuaXphdGlvbjE="), - HTMLURL: Ptr("https://github.com/programming-elixir"), + HTMLURL: Ptr("https://example.com/programming-elixir"), Name: Ptr("Learn how to build fault tolerant applications"), - AvatarURL: Ptr("https://avatars.githubusercontent.com/u/9919?v=4"), + AvatarURL: Ptr("https://example.com/avatars/u/9919?v=4"), }, - URL: Ptr("https://classroom.github.com/classrooms/1-programming-elixir"), + URL: Ptr("https://example.com/classrooms/programming"), } if !cmp.Equal(classroom, want) { @@ -279,13 +279,13 @@ func TestClassroomService_ListClassrooms(t *testing.T) { "id": 1296269, "name": "Programming Elixir", "archived": false, - "url": "https://classroom.github.com/classrooms/1-programming-elixir" + "url": "https://example.com/classrooms/programming" }, { "id": 1296270, "name": "Advanced Programming", "archived": true, - "url": "https://classroom.github.com/classrooms/2-advanced-programming" + "url": "https://example.com/classrooms/2-advanced-programming" } ]`) }) @@ -302,13 +302,13 @@ func TestClassroomService_ListClassrooms(t *testing.T) { ID: Ptr(int64(1296269)), Name: Ptr("Programming Elixir"), Archived: Ptr(false), - URL: Ptr("https://classroom.github.com/classrooms/1-programming-elixir"), + URL: Ptr("https://example.com/classrooms/programming"), }, { ID: Ptr(int64(1296270)), Name: Ptr("Advanced Programming"), Archived: Ptr(true), - URL: Ptr("https://classroom.github.com/classrooms/2-advanced-programming"), + URL: Ptr("https://example.com/classrooms/2-advanced-programming"), }, } @@ -339,7 +339,7 @@ func TestClassroomService_ListClassroomAssignments(t *testing.T) { "public_repo": false, "title": "Intro to Binaries", "type": "individual", - "invite_link": "https://classroom.github.com/a/Lx7jiUgx", + "invite_link": "https://example.com/a/Lx7jiUgx", "invitations_enabled": true, "slug": "intro-to-binaries", "students_are_repo_admins": false, @@ -356,7 +356,7 @@ func TestClassroomService_ListClassroomAssignments(t *testing.T) { "id": 1296269, "name": "Programming Elixir", "archived": false, - "url": "https://classroom.github.com/classrooms/1-programming-elixir" + "url": "https://example.com/classrooms/programming" } }, { @@ -364,7 +364,7 @@ func TestClassroomService_ListClassroomAssignments(t *testing.T) { "public_repo": true, "title": "Advanced Programming", "type": "group", - "invite_link": "https://classroom.github.com/a/AdvancedProg", + "invite_link": "https://example.com/a/AdvancedProg", "invitations_enabled": true, "slug": "advanced-programming", "students_are_repo_admins": true, @@ -381,7 +381,7 @@ func TestClassroomService_ListClassroomAssignments(t *testing.T) { "id": 1296269, "name": "Programming Elixir", "archived": false, - "url": "https://classroom.github.com/classrooms/1-programming-elixir" + "url": "https://example.com/classrooms/programming" } } ]`) @@ -400,7 +400,7 @@ func TestClassroomService_ListClassroomAssignments(t *testing.T) { PublicRepo: Ptr(false), Title: Ptr("Intro to Binaries"), Type: Ptr("individual"), - InviteLink: Ptr("https://classroom.github.com/a/Lx7jiUgx"), + InviteLink: Ptr("https://example.com/a/Lx7jiUgx"), InvitationsEnabled: Ptr(true), Slug: Ptr("intro-to-binaries"), StudentsAreRepoAdmins: Ptr(false), @@ -417,7 +417,7 @@ func TestClassroomService_ListClassroomAssignments(t *testing.T) { ID: Ptr(int64(1296269)), Name: Ptr("Programming Elixir"), Archived: Ptr(false), - URL: Ptr("https://classroom.github.com/classrooms/1-programming-elixir"), + URL: Ptr("https://example.com/classrooms/programming"), }, }, { @@ -425,7 +425,7 @@ func TestClassroomService_ListClassroomAssignments(t *testing.T) { PublicRepo: Ptr(true), Title: Ptr("Advanced Programming"), Type: Ptr("group"), - InviteLink: Ptr("https://classroom.github.com/a/AdvancedProg"), + InviteLink: Ptr("https://example.com/a/AdvancedProg"), InvitationsEnabled: Ptr(true), Slug: Ptr("advanced-programming"), StudentsAreRepoAdmins: Ptr(true), @@ -442,7 +442,7 @@ func TestClassroomService_ListClassroomAssignments(t *testing.T) { ID: Ptr(int64(1296269)), Name: Ptr("Programming Elixir"), Archived: Ptr(false), - URL: Ptr("https://classroom.github.com/classrooms/1-programming-elixir"), + URL: Ptr("https://example.com/classrooms/programming"), }, }, } From 863baf5f21d82f78829dbe361f263f63d52b7c7b Mon Sep 17 00:00:00 2001 From: jferrl Date: Tue, 23 Sep 2025 15:27:24 +0200 Subject: [PATCH 9/9] Add bad options tests for ClassroomService methods Introduces test cases for invalid input options in GetAssignment, GetClassroom, ListClassrooms, and ListClassroomAssignments methods to improve error handling coverage. --- github/classroom_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/github/classroom_test.go b/github/classroom_test.go index c53af2cab00..eaacd8143d5 100644 --- a/github/classroom_test.go +++ b/github/classroom_test.go @@ -201,6 +201,11 @@ func TestClassroomService_GetAssignment(t *testing.T) { } const methodName = "GetAssignment" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Classroom.GetAssignment(ctx, -1) + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { got, resp, err := client.Classroom.GetAssignment(ctx, 12) if got != nil { @@ -258,6 +263,11 @@ func TestClassroomService_GetClassroom(t *testing.T) { } const methodName = "GetClassroom" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Classroom.GetClassroom(ctx, -1) + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { got, resp, err := client.Classroom.GetClassroom(ctx, 1296269) if got != nil { @@ -452,6 +462,11 @@ func TestClassroomService_ListClassroomAssignments(t *testing.T) { } const methodName = "ListClassroomAssignments" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Classroom.ListClassroomAssignments(ctx, -1, opt) + return err + }) + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { got, resp, err := client.Classroom.ListClassroomAssignments(ctx, 1296269, opt) if got != nil {