зеркало из https://github.com/golang/build.git
342 строки
9.2 KiB
Go
342 строки
9.2 KiB
Go
// 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)
|
|
}
|
|
}
|
|
}
|