4
1
Fork 0

More tests and test tools
continuous-integration/drone/push Build is passing Details

pull/24/head
Ambrose Chua 2019-09-28 23:01:36 +08:00
parent e6499279ff
commit 079dc940a3
Signed by: ambrose
GPG Key ID: BC367D33F140B5C2
10 changed files with 199 additions and 27 deletions

34
Makefile Normal file
View File

@ -0,0 +1,34 @@
GOCMD=go
GORUN=$(GOCMD) run
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
DOCKERCOMPOSE=docker-compose
BINARY_NAME=core
DOCKERCOMPOSE_INTEGRATION_CONFIG=docker-compose.integration.yml
all: test_unit build
build:
$(GOBUILD) -o $(BINARY_NAME) -v
test: test_unit test_integration
test_unit:
$(GOTEST) -tags=unit -v -cover
test_integration: test_integration_prepare
$(GOTEST) -tags=integration -v -cover
test_integration_prepare:
$(GORUN) scripts/testutils.go isrunning || $(DOCKERCOMPOSE) -f $(DOCKERCOMPOSE_INTEGRATION_CONFIG) up -d
$(GORUN) scripts/testutils.go wait
test_integration_cleanup:
$(DOCKERCOMPOSE) -f $(DOCKERCOMPOSE_INTEGRATION_CONFIG) down
clean:
$(GOCLEAN)
rm -f $(BINARY_NAME)

View File

@ -88,7 +88,7 @@ func (h *Handler) GetContacts(w http.ResponseWriter, r *http.Request, p httprout
log.Print(err)
return
}
contacts = append(contacts, User{id, username, bio, profilePic, firstName, lastName, phone})
contacts = append(contacts, User{id, &username, bio, profilePic, firstName, lastName, phone})
}
// Respond

88
contact_test.go Normal file
View File

@ -0,0 +1,88 @@
// +build integration
package main
import (
"bytes"
"database/sql"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
// "github.com/google/go-cmp/cmp"
)
func TestContact(t *testing.T) {
db := connect()
defer db.Close()
h := NewHandler(db)
r := NewRouter(h)
setupUsers(t, db, r)
t.Run("Create", testCreateContact(db, r))
}
func setupUsers(t *testing.T, db *sql.DB, router http.Handler) {
users := []User{
User{
PhoneNumber: "+65 9999 0001",
FirstName: "Contact 1",
LastName: "User",
},
User{
PhoneNumber: "+65 9999 0002",
FirstName: "Contact 2",
LastName: "User",
},
User{
PhoneNumber: "+65 9999 0003",
FirstName: "Contact 3",
LastName: "User",
},
}
for _, user := range users {
b, _ := json.Marshal(user)
w := httptest.NewRecorder()
r := httptest.NewRequest("POST", "/user", bytes.NewBuffer(b))
router.ServeHTTP(w, r)
assertCode(t, w, 200)
}
}
func testCreateContact(db *sql.DB, router http.Handler) func(t *testing.T) {
return func(t *testing.T) {
/*
// Setup
mockUser := &User{
PhoneNumber: "+65 99999999",
FirstName: "Test",
LastName: "User 1",
}
b, _ := json.Marshal(mockUser)
// Test
w := httptest.NewRecorder()
r := httptest.NewRequest("POST", "/user", bytes.NewBuffer(b))
router.ServeHTTP(w, r)
assertCode(t, w, 200)
// Assert
got, want := new(User), mockUser
wantPhone, _ := ParsePhone(want.PhoneNumber)
json.NewDecoder(w.Body).Decode(got)
if got.FirstName != want.FirstName || got.LastName != want.LastName || got.PhoneNumber != wantPhone {
t.Error("Wanted a User with same FirstName, LastName, PhoneNumber. Got something else")
}
assertDB(t, db, `SELECT * FROM "user" WHERE phone_number = '+65 9999 9999' AND first_name = 'Test' AND last_name = 'User 1'`)
*/
}
}

View File

@ -367,7 +367,7 @@ func (h *Handler) GetConversationMembers(w http.ResponseWriter, r *http.Request,
log.Print(err)
return
}
users = append(users, User{ID: id, Username: username, Bio: bio, ProfilePic: profilePic, FirstName: firstName, LastName: lastName, PhoneNumber: phoneNumber})
users = append(users, User{ID: id, Username: &username, Bio: bio, ProfilePic: profilePic, FirstName: firstName, LastName: lastName, PhoneNumber: phoneNumber})
}
// Respond

2
go.mod
View File

@ -10,3 +10,5 @@ require (
github.com/ttacon/libphonenumber v1.0.0
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
)
go 1.13

View File

@ -1,7 +1,7 @@
CREATE TABLE IF NOT EXISTS "user" (
id BYTEA PRIMARY KEY,
username VARCHAR(63555),
username VARCHAR(63555) UNIQUE,
bio VARCHAR(63535) DEFAULT '',
profile_pic VARCHAR(63535) DEFAULT '',
first_name VARCHAR(65535) DEFAULT '',

59
scripts/testutils.go Normal file
View File

@ -0,0 +1,59 @@
package main
import (
"database/sql"
"flag"
"log"
"os"
"time"
"github.com/joho/godotenv"
_ "github.com/lib/pq"
)
func init() {
// Load .env
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
}
}
func main() {
flag.Parse()
exit := 1
if flag.Arg(0) == "isrunning" {
exit = isrunning()
} else if flag.Arg(0) == "wait" {
exit = wait()
} else {
log.Print("No command specified")
}
os.Exit(exit)
}
func isrunning() int {
db, err := sql.Open("postgres", os.Getenv("POSTGRES"))
if err != nil {
return 1
}
defer db.Close()
err = db.Ping()
if err != nil {
return 1
}
return 0
}
func wait() int {
for i := 0; i < 60; i += 1 {
timer := time.NewTimer(1 * time.Second)
if isrunning() == 0 {
return 0
}
<-timer.C
}
log.Print("Timed out trying to connect to postgres")
return 1
}

View File

@ -1,5 +1,7 @@
package main
// String pointer means nullable
type Conversation struct {
ID string `json:"id"` // id
Title string `json:"title"` // title
@ -9,13 +11,13 @@ type Conversation struct {
}
type User struct {
ID string `json:"id"` // id
Username string `json:"username"` // username
Bio string `json:"bio"` // bio
ProfilePic string `json:"profile_pic"` // profile_pic
FirstName string `json:"first_name"` // first_name
LastName string `json:"last_name"` // last_name
PhoneNumber string `json:"phone_number"` // phone_number
ID string `json:"id"` // id
Username *string `json:"username"` // username
Bio string `json:"bio"` // bio
ProfilePic string `json:"profile_pic"` // profile_pic
FirstName string `json:"first_name"` // first_name
LastName string `json:"last_name"` // last_name
PhoneNumber string `json:"phone_number"` // phone_number
}
type PhoneNumber struct {

13
user.go
View File

@ -149,19 +149,6 @@ func (h *Handler) UpdateUser(w http.ResponseWriter, r *http.Request, p httproute
return
}
// Check for duplicate username
var _id string
err = h.db.QueryRow(`
SELECT id FROM "user" WHERE "user".id <> $1 AND "user".username = $2
`, userID, user.Username).Scan(&_id)
if err == nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
} else if err != sql.ErrNoRows {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
// Update
_, err = h.db.Exec(`
UPDATE "user"

View File

@ -28,7 +28,7 @@ func testCreateUser(db *sql.DB, router http.Handler) func(t *testing.T) {
return func(t *testing.T) {
// Setup
mockUser := &User{
mockUser := User{
PhoneNumber: "+65 99999999",
FirstName: "Test",
LastName: "User 1",
@ -59,7 +59,7 @@ func testGetUserByPhone(db *sql.DB, router http.Handler) func(t *testing.T) {
return func(t *testing.T) {
// Setup
mockUser := &User{
mockUser := User{
PhoneNumber: "+65 99999998",
FirstName: "Test",
LastName: "User 2",
@ -94,7 +94,7 @@ func testGetUser(db *sql.DB, router http.Handler) func(t *testing.T) {
return func(t *testing.T) {
// Setup
mockUser := &User{
mockUser := User{
PhoneNumber: "+65 99999997",
FirstName: "User",
LastName: "Test 2",
@ -129,7 +129,7 @@ func testUpdateUser(db *sql.DB, router http.Handler) func(t *testing.T) {
return func(t *testing.T) {
// Setup
mockUser := &User{
mockUser := User{
PhoneNumber: "+65 99999996",
FirstName: "User",
LastName: "Test 3",