tsk-27: Added endpoint to delete scheduled message event (#31)

Closes #27

Reviewed-on: phoenix/textsender-api#31
Co-authored-by: phoenix <kundeng00@pm.me>
Co-committed-by: phoenix <kundeng00@pm.me>
This commit is contained in:
phoenix
2025-11-11 18:35:04 +00:00
committed by phoenix
parent 2716bb50d3
commit d191d6a9c1
7 changed files with 221 additions and 45 deletions
+1
View File
@@ -8,3 +8,4 @@ const ADD_CONTACT_ENDPOINT = "/api/v1/contact/new"
const ScheduleMessageEndpoint = "/api/v1/schedule/message"
const AddEventToScheduledMessageEndpoint = "/api/v1/schedule/message/event"
const GetScheduledMessageEventEndpoint = "/api/v1/schedule/message/event/{id}"
const DeleteScheduledMessageEventEndpoint = "/api/v1/schedule/message/event/{id}"
+66 -3
View File
@@ -27,6 +27,11 @@ type GetScheduledMessageEventResponse struct {
Data []scheduling.ScheduledMessageEvent `json:"data"`
}
type DeleteScheduledMessageEventResponse struct {
Message string `json:"message"`
Data []scheduling.ScheduledMessageEvent `json:"data"`
}
type ScheduledMessageEventHandler struct {
ScheduledMessageEventStore store.ScheduledMessageEventStore
ScheduledMessageStore store.ScheduledMessageStore
@@ -127,9 +132,67 @@ func (s *ScheduledMessageEventHandler) GetScheduledMessageEvent(w http.ResponseW
resp.Message = err.Error()
statusCode = http.StatusInternalServerError
} else {
resp.Message = "Successful"
statusCode = http.StatusOK
resp.Data = append(resp.Data, *event)
if event != nil {
resp.Message = "Successful"
statusCode = http.StatusOK
resp.Data = append(resp.Data, *event)
} else {
statusCode = http.StatusNotFound
resp.Message = "Scheduled message event not found"
}
}
}
RespondWithJSON(w, statusCode, &resp)
}
func (s *ScheduledMessageEventHandler) DeleteScheduledMessageEvent(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodDelete {
http.Error(w, "Metnot allowed", http.StatusMethodNotAllowed)
return
}
id := chi.URLParam(r, "id")
if len(id) == 0 {
pathParts := strings.Split(r.URL.Path, "/")
if len(pathParts) < 7 {
http.Error(w, "Id not provided", http.StatusBadRequest)
return
} else {
id = pathParts[6]
}
}
var resp DeleteScheduledMessageEventResponse
var statusCode int
if parsedId, err := uuid.Parse(id); err != nil {
resp.Message = err.Error()
statusCode = http.StatusBadRequest
} else {
ctx := r.Context()
if event, err := s.ScheduledMessageEventStore.Get(ctx, parsedId); err != nil {
resp.Message = err.Error()
statusCode = http.StatusInternalServerError
} else {
if schMsg, err := s.ScheduledMessageStore.Get(ctx, event.ScheduledMessageId); err != nil {
resp.Message = err.Error()
statusCode = http.StatusInternalServerError
} else {
if schMsg.Status == scheduling.Pending {
if err = s.ScheduledMessageEventStore.Delete(ctx, event.Id); err != nil {
resp.Message = err.Error()
statusCode = http.StatusInternalServerError
} else {
resp.Message = "Successful"
resp.Data = append(resp.Data, *event)
statusCode = http.StatusOK
}
} else {
statusCode = http.StatusBadRequest
resp.Message = "Invalid status"
}
}
}
}
@@ -18,6 +18,13 @@ import (
"git.kundeng.us/phoenix/textsender-api/internal/store/mock"
)
var (
recipientId = uuid.New()
messageId = uuid.New()
scheduledMessageId = uuid.New()
testUserId = uuid.New()
)
type CreateScheduledMessageEventRequest struct {
RecipientId uuid.UUID `json:"recipient_id"`
MessageId uuid.UUID `json:"message_id"`
@@ -39,21 +46,9 @@ func TestCreateScheduledMessageEventWithMock(t *testing.T) {
scheduledMessageId := uuid.New()
testUserId := uuid.New()
con := contact.Contact{}
con.Id = recipientId
con.PhoneNumber = "+10123456789"
con.UserId = testUserId
msg := message.Message{}
msg.Id = messageId
msg.Content = "Oh how the might have fallen"
msg.UserId = testUserId
schMsg := scheduling.ScheduledMessage{}
schMsg.Id = scheduledMessageId
schMsg.UserId = testUserId
schMsg.Scheduled = now.Add(20 * time.Minute)
schMsg.Status = scheduling.Pending
con := testContact(recipientId, testUserId)
msg := testMessage(messageId, testUserId)
schMsg := testScheduledMessage(scheduledMessageId, testUserId, now)
ctx := t.Context()
@@ -101,26 +96,10 @@ func TestGetScheduledMessageEventWithMock(t *testing.T) {
scheduledMessageId := uuid.New()
testUserId := uuid.New()
con := contact.Contact{}
con.Id = recipientId
con.PhoneNumber = "+10123456789"
con.UserId = testUserId
msg := message.Message{}
msg.Id = messageId
msg.Content = "Oh how the might have fallen"
msg.UserId = testUserId
schMsg := scheduling.ScheduledMessage{}
schMsg.Id = scheduledMessageId
schMsg.UserId = testUserId
schMsg.Scheduled = now.Add(20 * time.Minute)
schMsg.Status = scheduling.Pending
event := scheduling.ScheduledMessageEvent{}
event.MessageId = msg.Id
event.RecipientId = con.Id
event.ScheduledMessageId = schMsg.Id
con := testContact(recipientId, testUserId)
msg := testMessage(messageId, testUserId)
schMsg := testScheduledMessage(scheduledMessageId, testUserId, now)
event := testScheduledMessageEvent(msg.Id, con.Id, schMsg.Id)
ctx := t.Context()
@@ -152,3 +131,75 @@ func TestGetScheduledMessageEventWithMock(t *testing.T) {
assert.NotEmpty(t, msgEvent.Created, "Created date should not be empty")
}
func TestDeleteScheduledMessageEventWithMock(t *testing.T) {
now := time.Now()
contactStore := mock.NewMockContactStore()
messageStore := mock.NewMockMessageStore()
schMsgStore := mock.NewMockScheduledMessageStore()
schMsgEventStore := mock.NewMockScheduledMessageEventStore()
handler := NewScheduledMessageEventHandler(schMsgEventStore, schMsgStore)
con := testContact(recipientId, testUserId)
msg := testMessage(messageId, testUserId)
schMsg := testScheduledMessage(scheduledMessageId, testUserId, now)
event := testScheduledMessageEvent(msg.Id, con.Id, schMsg.Id)
ctx := t.Context()
if err := contactStore.CreateContact(ctx, &con); err != nil {
assert.NoError(t, err, "Error creating contact: %v", err)
} else if err = messageStore.CreateMessage(ctx, &msg); err != nil {
assert.NoError(t, err, "Error creating message: %v", err)
} else if err = schMsgStore.CreateScheduledMessage(ctx, &schMsg); err != nil {
assert.NoError(t, err, "Error creating scheduled message: %v", err)
} else if err = schMsgEventStore.CreateScheduledMessageEvent(ctx, &event); err != nil {
assert.NoError(t, err, "Error creating scheduled message event: %v", err)
}
endpointValue := strings.Replace(endpoint.DeleteScheduledMessageEventEndpoint, "{id}", event.Id.String(), 1)
req, _ := http.NewRequest("DELETE", endpointValue, nil)
rr := httptest.NewRecorder()
handler.DeleteScheduledMessageEvent(rr, req)
assert.Equal(t, http.StatusOK, rr.Code)
var response DeleteScheduledMessageEventResponse
err := json.Unmarshal(rr.Body.Bytes(), &response)
assert.NoError(t, err, "Error creating event %v", err)
assert.NotEmpty(t, response.Data, "No event created")
msgEvent := response.Data[0]
assert.NotEmpty(t, msgEvent.Created, "Created date should not be empty")
}
func testContact(id uuid.UUID, userId uuid.UUID) contact.Contact {
if id == uuid.Nil {
return contact.Contact{Id: uuid.New(), PhoneNumber: "+10123456789", UserId: userId}
} else {
return contact.Contact{Id: id, PhoneNumber: "+10123456789", UserId: userId}
}
}
func testMessage(id uuid.UUID, userId uuid.UUID) message.Message {
if id == uuid.Nil {
return message.Message{Id: uuid.New(), Content: "Oh how the mighty have fallen", UserId: userId}
} else {
return message.Message{Id: id, Content: "Oh how the mighty have fallen", UserId: userId}
}
}
func testScheduledMessage(id uuid.UUID, userId uuid.UUID, now time.Time) scheduling.ScheduledMessage {
if id == uuid.Nil {
return scheduling.ScheduledMessage{Id: uuid.New(), UserId: userId, Scheduled: now.Add(20 * time.Minute), Status: scheduling.Pending}
} else {
return scheduling.ScheduledMessage{Id: id, UserId: userId, Scheduled: now.Add(20 * time.Minute), Status: scheduling.Pending}
}
}
func testScheduledMessageEvent(messageId, recipientId, scheduledMessageId uuid.UUID) scheduling.ScheduledMessageEvent {
return scheduling.ScheduledMessageEvent{MessageId: messageId, RecipientId: recipientId, ScheduledMessageId: scheduledMessageId}
}