blob: e86566748bf56db2ef6070ae9a2f9891795bcdf8 [file] [log] [blame]
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gerrit
import (
"context"
"errors"
"io"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"time"
)
// taken from https://go-review.googlesource.com/projects/go
var exampleProjectResponse = []byte(`)]}'
{
"id": "go",
"name": "go",
"parent": "All-Projects",
"description": "The Go Programming Language",
"state": "ACTIVE",
"web_links": [
{
"name": "gitiles",
"url": "https://go.googlesource.com/go/",
"target": "_blank"
}
]
}
`)
func TestGetProjectInfo(t *testing.T) {
hitServer := false
path := ""
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
hitServer = true
path = r.URL.Path
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(200)
w.Write(exampleProjectResponse)
}))
defer s.Close()
c := NewClient(s.URL, NoAuth)
info, err := c.GetProjectInfo(context.Background(), "go")
if err != nil {
t.Fatal(err)
}
if !hitServer {
t.Errorf("expected to hit test server, didn't")
}
if path != "/projects/go" {
t.Errorf("expected Path to be '/projects/go', got %s", path)
}
if info.Name != "go" {
t.Errorf("expected Name to be 'go', got %s", info.Name)
}
}
func TestProjectNotFound(t *testing.T) {
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
w.WriteHeader(404)
w.Write([]byte("Not found: unknown"))
}))
defer s.Close()
c := NewClient(s.URL, NoAuth)
_, err := c.GetProjectInfo(context.Background(), "unknown")
if !errors.Is(err, ErrResourceNotExist) {
t.Errorf("expected to get ErrResourceNotExist, got %v", err)
}
}
func TestContextError(t *testing.T) {
c := NewClient("http://localhost", NoAuth)
yearsAgo, _ := time.Parse("2006", "2006")
ctx, cancel := context.WithDeadline(context.Background(), yearsAgo)
defer cancel()
_, err := c.GetProjectInfo(ctx, "unknown")
if err == nil {
t.Errorf("expected non-nil error, got nil")
}
uerr, ok := err.(*url.Error)
if !ok {
t.Errorf("expected url.Error, got %#v", err)
}
if uerr.Err != context.DeadlineExceeded {
t.Errorf("expected DeadlineExceeded error, got %v", uerr.Err)
}
}
var getChangeResponse = []byte(`)]}'
{
"id": "build~master~I92989e0231299ed305ddfbbe6034d293f1c87470",
"project": "build",
"branch": "master",
"hashtags": [],
"change_id": "I92989e0231299ed305ddfbbe6034d293f1c87470",
"subject": "devapp: fix tests",
"status": "ABANDONED",
"created": "2017-07-13 06:09:10.000000000",
"updated": "2017-07-14 16:31:32.000000000",
"insertions": 1,
"deletions": 1,
"unresolved_comment_count": 0,
"has_review_started": true,
"_number": 48330,
"owner": {
"_account_id": 13437
},
"messages": [
{
"id": "f9fcf0ff9eb58fc8edd989f8bbb3500ff73f9b11",
"author": {
"_account_id": 22285
},
"real_author": {
"_account_id": 22285
},
"date": "2017-07-13 06:14:48.000000000",
"message": "Patch Set 1:\n\nCheck out https://go-review.googlesource.com/c/48350/ :)",
"_revision_number": 1
}
]
}`)
func TestGetChange(t *testing.T) {
hitServer := false
uri := ""
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
hitServer = true
uri = r.URL.RequestURI()
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(200)
w.Write(getChangeResponse)
}))
defer s.Close()
c := NewClient(s.URL, NoAuth)
info, err := c.GetChange(context.Background(), "48330", QueryChangesOpt{
Fields: []string{"MESSAGES"},
})
if err != nil {
t.Fatal(err)
}
if !hitServer {
t.Errorf("expected to hit test server, didn't")
}
if want := "/changes/48330?o=MESSAGES"; uri != want {
t.Errorf("expected RequestURI to be %q, got %q", want, uri)
}
if len(info.Messages) != 1 {
t.Errorf("expected message length to be 1, got %d", len(info.Messages))
}
msg := info.Messages[0].Message
if !strings.Contains(msg, "Check out") {
t.Errorf("expected to find string in Message, got %s", msg)
}
}
func TestGetChangeError(t *testing.T) {
hitServer := false
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
hitServer = true
w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
w.WriteHeader(404)
io.WriteString(w, "Not found: 99999")
}))
defer s.Close()
c := NewClient(s.URL, NoAuth)
_, err := c.GetChange(context.Background(), "99999", QueryChangesOpt{
Fields: []string{"MESSAGES"},
})
if !hitServer {
t.Errorf("expected to hit test server, didn't")
}
if !errors.Is(err, ErrResourceNotExist) {
t.Errorf("expected ErrResourceNotExist, got %v", err)
}
}
var queryAccountsResponse = []byte(`)]}'
[
{
"_account_id": 1,
"name": "John Doe",
"email": "john@doe.com"
},
{
"_account_id": 2,
"name": "Jane Doe",
"email": "jane@doe.com",
"_more_accounts": true
}
]`)
func TestQueryAccounts(t *testing.T) {
hitServer := false
uri := ""
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
hitServer = true
uri = r.URL.RequestURI()
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(200)
w.Write(queryAccountsResponse)
}))
defer s.Close()
c := NewClient(s.URL, NoAuth)
info, err := c.QueryAccounts(context.Background(), "is:active", QueryAccountsOpt{
Fields: []string{"DETAILS"},
N: 2,
})
if err != nil {
t.Fatal(err.Error())
}
if !hitServer {
t.Errorf("expected to hit test server, didn't")
}
if want := "/accounts/?n=2&o=DETAILS&q=is%3Aactive"; uri != want {
t.Errorf("expected RequestURI to be %q, got %q", want, uri)
}
if len(info) != 2 {
t.Errorf("expected accounts length to be 2, got %d", len(info))
}
if info[0].NumericID != 1 || info[0].Name != "John Doe" || info[0].Email != "john@doe.com" {
t.Errorf("expected to match John Doe in account, got %v", info[0])
}
if info[1].NumericID != 2 || info[1].Name != "Jane Doe" || info[1].Email != "jane@doe.com" {
t.Errorf("expected to match Jane Doe in account, got %v", info[1])
}
if info[0].MoreAccounts {
t.Errorf("expected to MoreAccounts to be false for John Doe")
}
if !info[1].MoreAccounts {
t.Errorf("expected to MoreAccounts to be true for Jane Doe")
}
}
func TestTimeStampMarshalJson(t *testing.T) {
ts := TimeStamp(time.Date(1888, 6, 24, 6, 8, 30, 123456789, time.FixedZone("+1", 3600)))
b, err := ts.MarshalJSON()
if err != nil {
t.Errorf("unexpected err %v", err)
}
expected := `"1888-06-24 05:08:30.123456789"`
if string(b) != expected {
t.Errorf("expected %q, got %q", expected, b)
}
}
func TestTimeStampUnmarshalJson(t *testing.T) {
var ts TimeStamp
err := ts.UnmarshalJSON([]byte(`"1888-06-24 05:08:30.123456789"`))
if err != nil {
t.Errorf("unexpected err %v", err)
}
expected := time.Date(1888, 6, 24, 5, 8, 30, 123456789, time.UTC)
if !ts.Time().Equal(expected) {
t.Errorf("expected %v, got %v", expected, ts.Time())
}
}
// taken from https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#list-tags
var exampleProjectTagsResponse = []byte(` )]}'
[
{
"ref": "refs/tags/v1.0",
"revision": "49ce77fdcfd3398dc0dedbe016d1a425fd52d666",
"object": "1624f5af8ae89148d1a3730df8c290413e3dcf30",
"message": "Annotated tag",
"tagger": {
"name": "David Pursehouse",
"email": "david.pursehouse@sonymobile.com",
"date": "2014-10-06 07:35:03.000000000",
"tz": 540
}
},
{
"ref": "refs/tags/v2.0",
"revision": "1624f5af8ae89148d1a3730df8c290413e3dcf30"
}
]
`)
func TestGetProjectTags(t *testing.T) {
hitServer := false
path := ""
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
hitServer = true
path = r.URL.Path
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(200)
w.Write(exampleProjectTagsResponse)
}))
defer s.Close()
c := NewClient(s.URL, NoAuth)
tags, err := c.GetProjectTags(context.Background(), "go")
if err != nil {
t.Fatal(err)
}
if !hitServer {
t.Errorf("expected to hit test server, didn't")
}
if path != "/projects/go/tags/" {
t.Errorf("expected Path to be '/projects/go/tags/', got %s", path)
}
expectedTags := map[string]TagInfo{
"refs/tags/v1.0": TagInfo{
Ref: "refs/tags/v1.0",
Revision: "49ce77fdcfd3398dc0dedbe016d1a425fd52d666",
Object: "1624f5af8ae89148d1a3730df8c290413e3dcf30",
Message: "Annotated tag",
Tagger: &GitPersonInfo{
Name: "David Pursehouse",
Email: "david.pursehouse@sonymobile.com",
Date: TimeStamp(time.Date(2014, 10, 6, 7, 35, 3, 0, time.UTC)),
TZOffset: 540,
},
},
"refs/tags/v2.0": TagInfo{
Ref: "refs/tags/v2.0",
Revision: "1624f5af8ae89148d1a3730df8c290413e3dcf30",
},
}
if len(tags) != len(expectedTags) {
t.Errorf("expected %d tags, got %d", len(expectedTags), len(tags))
}
for ref, tag := range tags {
expectedTag, found := expectedTags[ref]
if !found {
t.Errorf("unexpected tag %q", ref)
}
if !tag.Equal(&expectedTag) {
t.Errorf("tags don't match (expected %#v and got %#v)", expectedTag, tag)
}
}
}