parent
fffda5271b
commit
e0d3293eb7
2
Makefile
2
Makefile
|
@ -45,7 +45,7 @@ test_unit:
|
||||||
test_integration: test_integration_prepare
|
test_integration: test_integration_prepare
|
||||||
$(GOTEST) -tags=integration -v -cover
|
$(GOTEST) -tags=integration -v -cover
|
||||||
test_integration_prepare:
|
test_integration_prepare:
|
||||||
$(GORUN) scripts/testutils.go isrunning || $(DOCKERCOMPOSE) -f $(DOCKERCOMPOSE_INTEGRATION_CONFIG) up -d
|
$(GORUN) scripts/testutils.go isrunning || ($(DOCKERCOMPOSE) -f $(DOCKERCOMPOSE_INTEGRATION_CONFIG) up -d && echo "$(shell tput bold)NOTE: Started some containers, cleanup with 'make test_integration_cleanup'$(shell tput sgr0)")
|
||||||
$(GORUN) scripts/testutils.go wait
|
$(GORUN) scripts/testutils.go wait
|
||||||
test_integration_sql_shell:
|
test_integration_sql_shell:
|
||||||
$(DOCKERCOMPOSE) -f $(DOCKERCOMPOSE_INTEGRATION_CONFIG) exec pg psql -d core
|
$(DOCKERCOMPOSE) -f $(DOCKERCOMPOSE_INTEGRATION_CONFIG) exec pg psql -d core
|
||||||
|
|
|
@ -37,8 +37,8 @@ func (h *Handler) CreateConversation(w http.ResponseWriter, r *http.Request, p h
|
||||||
|
|
||||||
// Conversation
|
// Conversation
|
||||||
_, err1 := tx.Exec(`
|
_, err1 := tx.Exec(`
|
||||||
INSERT INTO "conversation" (id, title, dm, picture) VALUES ($1, $2, $3, $4)
|
INSERT INTO "conversation" (id, title, picture) VALUES ($1, $2, $3)
|
||||||
`, conversation.ID, conversation.Title, conversation.DM, conversation.Picture)
|
`, conversation.ID, conversation.Title, conversation.Picture)
|
||||||
// First member
|
// First member
|
||||||
_, err2 := tx.Exec(`
|
_, err2 := tx.Exec(`
|
||||||
INSERT INTO member ("user", "conversation") VALUES ($1, $2)
|
INSERT INTO member ("user", "conversation") VALUES ($1, $2)
|
||||||
|
@ -86,14 +86,9 @@ func (h *Handler) GetConversations(w http.ResponseWriter, r *http.Request, p htt
|
||||||
|
|
||||||
// Select
|
// Select
|
||||||
rows, err := h.db.Query(`
|
rows, err := h.db.Query(`
|
||||||
SELECT "conversation".id, CASE
|
SELECT "conversation".id, "conversation".title, "conversation".picture, member.pinned
|
||||||
WHEN "conversation".dm THEN (SELECT CONCAT("user".first_name, ' ', "user".last_name) FROM "user", member WHERE "user".id <> $1 AND "user".id = member.user AND member.conversation = "conversation".id)
|
FROM "conversation", member
|
||||||
ELSE title
|
WHERE member.conversation = "conversation".id AND member.user = $1
|
||||||
END AS title,
|
|
||||||
"conversation".picture,
|
|
||||||
member.pinned
|
|
||||||
FROM "conversation", member
|
|
||||||
WHERE member.conversation = "conversation".id AND member.user = $1
|
|
||||||
`, userID)
|
`, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||||
|
@ -128,14 +123,9 @@ func (h *Handler) GetConversation(w http.ResponseWriter, r *http.Request, p http
|
||||||
|
|
||||||
// Select
|
// Select
|
||||||
err := h.db.QueryRow(`
|
err := h.db.QueryRow(`
|
||||||
SELECT "conversation".id, CASE
|
SELECT "conversation".id, "conversation".title, "conversation".picture, member.pinned
|
||||||
WHEN "conversation".dm THEN (SELECT CONCAT("user".first_name, ' ', "user".last_name) FROM "user", member WHERE "user".id <> $1 AND "user".id = member.user AND member.conversation = "conversation".id)
|
FROM "conversation", member
|
||||||
ELSE title
|
WHERE member.conversation = "conversation".id AND member.user = $1 AND member.conversation = $2
|
||||||
END AS title,
|
|
||||||
"conversation" picture,
|
|
||||||
member.pinned
|
|
||||||
FROM "conversation", member
|
|
||||||
WHERE member.conversation = "conversation".id AND member.user = $1 AND member.conversation = $2
|
|
||||||
`, userID, conversationID).Scan(&conversation.ID, &conversation.Title, &conversation.Picture, &conversation.Pinned)
|
`, userID, conversationID).Scan(&conversation.ID, &conversation.Title, &conversation.Picture, &conversation.Pinned)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
@ -289,7 +279,9 @@ func (h *Handler) DeleteConversation(w http.ResponseWriter, r *http.Request, p h
|
||||||
|
|
||||||
func (h *Handler) CreateConversationMember(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
func (h *Handler) CreateConversationMember(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||||
// Parse
|
// Parse
|
||||||
userID := r.Context().Value("user").(string)
|
// We don't need the user ID here because when we first create a conversation, it should have no members
|
||||||
|
// TODO: conversations should have conversation owners?
|
||||||
|
//userID := r.Context().Value("user").(string)
|
||||||
conversationID := p.ByName("conversation")
|
conversationID := p.ByName("conversation")
|
||||||
member := User{}
|
member := User{}
|
||||||
decoder := json.NewDecoder(r.Body)
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
@ -308,65 +300,7 @@ func (h *Handler) CreateConversationMember(w http.ResponseWriter, r *http.Reques
|
||||||
// Log
|
// Log
|
||||||
log.Print(member)
|
log.Print(member)
|
||||||
|
|
||||||
// Check for existing DM
|
// TODO: When we need stronger constraints, add some policy around existing conversations with a title set
|
||||||
var dmID string
|
|
||||||
err = h.db.QueryRow(`
|
|
||||||
SELECT "conversation".id FROM "conversation", "member"
|
|
||||||
WHERE
|
|
||||||
"conversation".dm = TRUE
|
|
||||||
AND "conversation".id = "member".conversation
|
|
||||||
AND "member".user = $1
|
|
||||||
`, member.ID).Scan(&dmID)
|
|
||||||
if err != sql.ErrNoRows {
|
|
||||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
} else if err == nil {
|
|
||||||
w.Write([]byte(dmID))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for valid conversation and prevent duplicate entries
|
|
||||||
var test string
|
|
||||||
err = h.db.QueryRow(`
|
|
||||||
SELECT "conversation".id FROM "conversation", "member"
|
|
||||||
WHERE
|
|
||||||
"conversation".id = $1
|
|
||||||
AND (
|
|
||||||
"conversation".dm = FALSE
|
|
||||||
OR (SELECT
|
|
||||||
COUNT("member".user)
|
|
||||||
FROM "member"
|
|
||||||
WHERE "member".conversation = $1)
|
|
||||||
<= 2)
|
|
||||||
AND "member".conversation = "conversation".id
|
|
||||||
AND "member".user <> $2
|
|
||||||
`, conversationID, member.ID).Scan(&test)
|
|
||||||
switch {
|
|
||||||
case err == sql.ErrNoRows:
|
|
||||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
case err != nil:
|
|
||||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
||||||
log.Print(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check user adding the user is in conversation
|
|
||||||
var conversationID2 string
|
|
||||||
err = h.db.QueryRow(`
|
|
||||||
SELECT id FROM "conversation"
|
|
||||||
INNER JOIN member
|
|
||||||
ON member.conversation = "conversation".id AND member.user = $1 AND member.conversation = $2
|
|
||||||
`, userID, conversationID).Scan(&conversationID2)
|
|
||||||
switch {
|
|
||||||
case err == sql.ErrNoRows:
|
|
||||||
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
|
||||||
return
|
|
||||||
case err != nil:
|
|
||||||
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
|
||||||
log.Print(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert
|
// Insert
|
||||||
_, err = h.db.Exec(`
|
_, err = h.db.Exec(`
|
||||||
|
|
|
@ -72,7 +72,6 @@ func testCreateConversation(db *sql.DB, router http.Handler, users []User) func(
|
||||||
// Test
|
// Test
|
||||||
mockConversation := &Conversation{
|
mockConversation := &Conversation{
|
||||||
Title: null.StringFrom("Test Conversation 1"),
|
Title: null.StringFrom("Test Conversation 1"),
|
||||||
DM: false,
|
|
||||||
}
|
}
|
||||||
b, _ := json.Marshal(mockConversation)
|
b, _ := json.Marshal(mockConversation)
|
||||||
|
|
||||||
|
@ -87,11 +86,11 @@ func testCreateConversation(db *sql.DB, router http.Handler, users []User) func(
|
||||||
// Assert
|
// Assert
|
||||||
got, want := &Conversation{}, mockConversation
|
got, want := &Conversation{}, mockConversation
|
||||||
json.NewDecoder(w.Body).Decode(&got)
|
json.NewDecoder(w.Body).Decode(&got)
|
||||||
if got.DM != want.DM || got.Title.String != want.Title.String {
|
if got.Title.String != want.Title.String {
|
||||||
t.Error("Wanted a Conversation with same Title, DM. Got something else")
|
t.Error("Wanted a Conversation with same Title. Got something else")
|
||||||
}
|
}
|
||||||
|
|
||||||
assertDB(t, db, `SELECT * FROM "conversation" WHERE title = $1 AND dm = $2`, mockConversation.Title, mockConversation.DM)
|
assertDB(t, db, `SELECT * FROM "conversation" WHERE title = $1`, mockConversation.Title)
|
||||||
assertDB(t, db, `SELECT * FROM member WHERE "user" = $1 AND "conversation" = $2`, users[0].ID, got.ID)
|
assertDB(t, db, `SELECT * FROM member WHERE "user" = $1 AND "conversation" = $2`, users[0].ID, got.ID)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -103,7 +102,6 @@ func testGetConversations(db *sql.DB, router http.Handler, users []User) func(t
|
||||||
// Setup
|
// Setup
|
||||||
mockConversation := &Conversation{
|
mockConversation := &Conversation{
|
||||||
Title: null.StringFrom("Test Conversation 2"),
|
Title: null.StringFrom("Test Conversation 2"),
|
||||||
DM: false,
|
|
||||||
}
|
}
|
||||||
bs, _ := json.Marshal(mockConversation)
|
bs, _ := json.Marshal(mockConversation)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ CREATE TABLE IF NOT EXISTS "user" (
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS "conversation" (
|
CREATE TABLE IF NOT EXISTS "conversation" (
|
||||||
id BYTEA PRIMARY KEY,
|
id BYTEA PRIMARY KEY,
|
||||||
dm BOOLEAN,
|
|
||||||
title VARCHAR(65535),
|
title VARCHAR(65535),
|
||||||
picture VARCHAR(63535)
|
picture VARCHAR(63535)
|
||||||
);
|
);
|
||||||
|
|
|
@ -47,7 +47,7 @@ func isrunning() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func wait() int {
|
func wait() int {
|
||||||
for i := 0; i < 60; i += 1 {
|
for i := 0; i < 120; i += 1 {
|
||||||
timer := time.NewTimer(1 * time.Second)
|
timer := time.NewTimer(1 * time.Second)
|
||||||
if isrunning() == 0 {
|
if isrunning() == 0 {
|
||||||
return 0
|
return 0
|
||||||
|
|
1
types.go
1
types.go
|
@ -21,7 +21,6 @@ type Member struct {
|
||||||
type Conversation struct {
|
type Conversation struct {
|
||||||
ID string `json:"id"` // id
|
ID string `json:"id"` // id
|
||||||
Title null.String `json:"title"` // title
|
Title null.String `json:"title"` // title
|
||||||
DM bool `json:"dm"` // dm
|
|
||||||
Picture null.String `json:"picture"` // picture
|
Picture null.String `json:"picture"` // picture
|
||||||
Pinned bool `json:"pinned"` // pinned
|
Pinned bool `json:"pinned"` // pinned
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue