tsk-11: Added endpoint to get Contact (#17)

Closes #11

Reviewed-on: phoenix/textsender-api#17
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
This commit is contained in:
phoenix
2025-11-06 20:09:52 +00:00
committed by phoenix
parent 507eb9eb09
commit acf414c876
5 changed files with 116 additions and 1 deletions
+1
View File
@@ -75,6 +75,7 @@ func main() {
router.Use(mdlware.JSONContentType) router.Use(mdlware.JSONContentType)
router.Handle(endpoint.ADD_CONTACT_ENDPOINT, mdlware.AuthMiddleware(jwtService)(http.HandlerFunc(contactHandler.AddContact))) router.Handle(endpoint.ADD_CONTACT_ENDPOINT, mdlware.AuthMiddleware(jwtService)(http.HandlerFunc(contactHandler.AddContact)))
router.Handle(endpoint.GET_CONTACT, mdlware.AuthMiddleware(jwtService)(http.HandlerFunc(contactHandler.GetContact)))
router.Handle(endpoint.ADD_MESSAGE, mdlware.AuthMiddleware(jwtService)(http.HandlerFunc(messageHandler.AddMessage))) router.Handle(endpoint.ADD_MESSAGE, mdlware.AuthMiddleware(jwtService)(http.HandlerFunc(messageHandler.AddMessage)))
// Start server // Start server
+82
View File
@@ -20,6 +20,11 @@ type AddContactResponse struct {
Data []contact.Contact `json:"data"` Data []contact.Contact `json:"data"`
} }
type GetContactResponse struct {
Message string `json:"message"`
Data []contact.Contact `json:"data"`
}
type ContactHandler struct { type ContactHandler struct {
ContactStore store.ContactStore ContactStore store.ContactStore
} }
@@ -70,3 +75,80 @@ func (c *ContactHandler) AddContact(w http.ResponseWriter, r *http.Request) {
RespondWithJSON(w, statusCode, &resp) RespondWithJSON(w, statusCode, &resp)
} }
func (c *ContactHandler) GetContact(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
fmt.Println("Method:", r.Method)
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
var id, userId uuid.UUID
queryParams := r.URL.Query()
// Check if parameter exists
if _, exists := queryParams["id"]; !exists {
if _, exists := queryParams["user_id"]; !exists {
fmt.Fprintf(w, "Name parameter not provided")
http.Error(w, "Query params", http.StatusBadRequest)
return
} else {
var err error
userId, err = uuid.Parse(queryParams.Get("user_id"))
if err != nil {
fmt.Fprintf(w, "Name parameter exists: %s", userId)
}
}
} else {
var err error
idTmp := queryParams.Get("id")
id, err = uuid.Parse(idTmp)
if err != nil {
fmt.Println("Error:", err)
http.Error(w, "Error parsing Id", http.StatusBadRequest)
return
}
}
var statusCode int
var resp GetContactResponse
ctx := r.Context()
if id != uuid.Nil {
fmt.Println("Checking with Id")
if con, err := c.ContactStore.GetContactByID(ctx, id); err == nil {
statusCode = http.StatusOK
resp.Message = "Successful"
resp.Data = append(resp.Data, *con)
} else {
statusCode = http.StatusInternalServerError
resp.Message = err.Error()
}
} else if userId != uuid.Nil {
fmt.Println("Checking with User Id")
if contacts, err := c.ContactStore.GetAllContacts(ctx); err == nil {
for _, con := range contacts {
if con.UserId == userId {
resp.Data = append(resp.Data, *con)
}
}
if len(resp.Data) > 0 {
statusCode = http.StatusOK
resp.Message = "Successful"
} else {
statusCode = http.StatusNotFound
resp.Message = "Contact not found"
}
} else {
statusCode = http.StatusInternalServerError
resp.Message = err.Error()
}
} else {
statusCode = http.StatusBadRequest
resp.Message = "Invalid query parameter"
}
RespondWithJSON(w, statusCode, &resp)
}
+31
View File
@@ -3,11 +3,13 @@ package handler
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"strings" "strings"
"testing" "testing"
"git.kundeng.us/phoenix/textsender-models/pkg/contact"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@@ -44,6 +46,35 @@ func TestCreateContactWithMock(t *testing.T) {
assert.NotNil(t, response.Data[0].Id, "Id should not be nil") assert.NotNil(t, response.Data[0].Id, "Id should not be nil")
} }
func TestGetContactWithMock(t *testing.T) {
mockstore := NewMockContactStore()
testUserId := uuid.New()
testCon := contact.Contact{PhoneNumber: "+12335403383", UserId: testUserId}
ctx := t.Context()
if err := mockstore.CreateContact(ctx, &testCon); err != nil {
assert.NoError(t, err, "Error creating contact")
return
}
url := fmt.Sprintf("%s?user_id=%s", endpoint.GET_CONTACT, testCon.UserId)
req, _ := http.NewRequest("GET", url, nil)
rr := httptest.NewRecorder()
contactHandler := NewContactHandler(mockstore)
contactHandler.GetContact(rr, req)
assert.Equal(t, http.StatusOK, rr.Code)
var response GetContactResponse
err := json.Unmarshal(rr.Body.Bytes(), &response)
assert.NoError(t, err, "Error getting contact %v", err)
assert.NotEmpty(t, response.Data, "No Contact retrieved")
assert.NotNil(t, response.Data[0].Id, "Id should not be nil")
}
func resetTestDB(t *testing.T) { func resetTestDB(t *testing.T) {
t.Helper() t.Helper()
_, err := db.Pool.Exec(context.Background(), "DELETE FROM contacts") _, err := db.Pool.Exec(context.Background(), "DELETE FROM contacts")
+2 -1
View File
@@ -2,4 +2,5 @@ package endpoint
const MESSAGE_DRAFT_ENDPOINT = "/api/v1/message/draft" const MESSAGE_DRAFT_ENDPOINT = "/api/v1/message/draft"
const ADD_MESSAGE = "/api/v1/message/new" const ADD_MESSAGE = "/api/v1/message/new"
const ADD_CONTACT_ENDPOINT = "/api/v1/contact" const GET_CONTACT = "/api/v1/contact"
const ADD_CONTACT_ENDPOINT = "/api/v1/contact/new"