More tests and test tools
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
e6499279ff
commit
079dc940a3
|
@ -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)
|
|
@ -88,7 +88,7 @@ func (h *Handler) GetContacts(w http.ResponseWriter, r *http.Request, p httprout
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
contacts = append(contacts, User{id, username, bio, profilePic, firstName, lastName, phone})
|
contacts = append(contacts, User{id, &username, bio, profilePic, firstName, lastName, phone})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Respond
|
// Respond
|
||||||
|
|
|
@ -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'`)
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -367,7 +367,7 @@ func (h *Handler) GetConversationMembers(w http.ResponseWriter, r *http.Request,
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
return
|
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
|
// Respond
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -10,3 +10,5 @@ require (
|
||||||
github.com/ttacon/libphonenumber v1.0.0
|
github.com/ttacon/libphonenumber v1.0.0
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS "user" (
|
CREATE TABLE IF NOT EXISTS "user" (
|
||||||
id BYTEA PRIMARY KEY,
|
id BYTEA PRIMARY KEY,
|
||||||
username VARCHAR(63555),
|
username VARCHAR(63555) UNIQUE,
|
||||||
bio VARCHAR(63535) DEFAULT '',
|
bio VARCHAR(63535) DEFAULT '',
|
||||||
profile_pic VARCHAR(63535) DEFAULT '',
|
profile_pic VARCHAR(63535) DEFAULT '',
|
||||||
first_name VARCHAR(65535) DEFAULT '',
|
first_name VARCHAR(65535) DEFAULT '',
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
16
types.go
16
types.go
|
@ -1,5 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
// String pointer means nullable
|
||||||
|
|
||||||
type Conversation struct {
|
type Conversation struct {
|
||||||
ID string `json:"id"` // id
|
ID string `json:"id"` // id
|
||||||
Title string `json:"title"` // title
|
Title string `json:"title"` // title
|
||||||
|
@ -9,13 +11,13 @@ type Conversation struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID string `json:"id"` // id
|
ID string `json:"id"` // id
|
||||||
Username string `json:"username"` // username
|
Username *string `json:"username"` // username
|
||||||
Bio string `json:"bio"` // bio
|
Bio string `json:"bio"` // bio
|
||||||
ProfilePic string `json:"profile_pic"` // profile_pic
|
ProfilePic string `json:"profile_pic"` // profile_pic
|
||||||
FirstName string `json:"first_name"` // first_name
|
FirstName string `json:"first_name"` // first_name
|
||||||
LastName string `json:"last_name"` // last_name
|
LastName string `json:"last_name"` // last_name
|
||||||
PhoneNumber string `json:"phone_number"` // phone_number
|
PhoneNumber string `json:"phone_number"` // phone_number
|
||||||
}
|
}
|
||||||
|
|
||||||
type PhoneNumber struct {
|
type PhoneNumber struct {
|
||||||
|
|
13
user.go
13
user.go
|
@ -149,19 +149,6 @@ func (h *Handler) UpdateUser(w http.ResponseWriter, r *http.Request, p httproute
|
||||||
return
|
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
|
// Update
|
||||||
_, err = h.db.Exec(`
|
_, err = h.db.Exec(`
|
||||||
UPDATE "user"
|
UPDATE "user"
|
||||||
|
|
|
@ -28,7 +28,7 @@ func testCreateUser(db *sql.DB, router http.Handler) func(t *testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
mockUser := &User{
|
mockUser := User{
|
||||||
PhoneNumber: "+65 99999999",
|
PhoneNumber: "+65 99999999",
|
||||||
FirstName: "Test",
|
FirstName: "Test",
|
||||||
LastName: "User 1",
|
LastName: "User 1",
|
||||||
|
@ -59,7 +59,7 @@ func testGetUserByPhone(db *sql.DB, router http.Handler) func(t *testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
mockUser := &User{
|
mockUser := User{
|
||||||
PhoneNumber: "+65 99999998",
|
PhoneNumber: "+65 99999998",
|
||||||
FirstName: "Test",
|
FirstName: "Test",
|
||||||
LastName: "User 2",
|
LastName: "User 2",
|
||||||
|
@ -94,7 +94,7 @@ func testGetUser(db *sql.DB, router http.Handler) func(t *testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
mockUser := &User{
|
mockUser := User{
|
||||||
PhoneNumber: "+65 99999997",
|
PhoneNumber: "+65 99999997",
|
||||||
FirstName: "User",
|
FirstName: "User",
|
||||||
LastName: "Test 2",
|
LastName: "Test 2",
|
||||||
|
@ -129,7 +129,7 @@ func testUpdateUser(db *sql.DB, router http.Handler) func(t *testing.T) {
|
||||||
return func(t *testing.T) {
|
return func(t *testing.T) {
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
mockUser := &User{
|
mockUser := User{
|
||||||
PhoneNumber: "+65 99999996",
|
PhoneNumber: "+65 99999996",
|
||||||
FirstName: "User",
|
FirstName: "User",
|
||||||
LastName: "Test 3",
|
LastName: "Test 3",
|
||||||
|
|
Loading…
Reference in New Issue