diff --git a/go.mod b/go.mod index 51f4ae7..fe6c45b 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module git.kundeng.us/phoenix/textsender-api go 1.25.4 require ( - git.kundeng.us/phoenix/swoosh v0.0.7-8-523c7cf67c-556 - git.kundeng.us/phoenix/textsender-models v0.0.12 + git.kundeng.us/phoenix/swoosh v0.1.0-main-3c1f8a1a27-556 + git.kundeng.us/phoenix/textsender-models v0.1.6-30-f4e2336771-556 github.com/go-chi/chi/v5 v5.2.3 github.com/go-chi/cors v1.2.2 github.com/golang-jwt/jwt/v5 v5.3.0 diff --git a/go.sum b/go.sum index 848543d..112117a 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ -git.kundeng.us/phoenix/swoosh v0.0.7-8-523c7cf67c-556 h1:vzTrhx7auc8OlUGmfTDektHXCkoFOKzVhdsW+6oKXMI= -git.kundeng.us/phoenix/swoosh v0.0.7-8-523c7cf67c-556/go.mod h1:OAh9jVBQ3vRJ1EHTM6pFyWd9eXf1H+CevbDKkJuoDZU= -git.kundeng.us/phoenix/textsender-models v0.0.12 h1:ps9H3FS5LyCwQhAiIvg4vYyfLZZ64dex1y9ytb0o9C4= -git.kundeng.us/phoenix/textsender-models v0.0.12/go.mod h1:9iPDQJg1Tc6WMNoW5+f8YKmnosMwlWHJ++hmxNLDEe0= +git.kundeng.us/phoenix/swoosh v0.1.0-main-3c1f8a1a27-556 h1:KsX+w6iUSPWajQs6fkpDhTBixcUjq9vb4NGXFWKA7fM= +git.kundeng.us/phoenix/swoosh v0.1.0-main-3c1f8a1a27-556/go.mod h1:XGXsm6S8+W52FXsMnYo4eOpILHAu5S86IgboZALfyQw= +git.kundeng.us/phoenix/textsender-models v0.1.6-30-f4e2336771-556 h1:869mq7lyB+XaNqJOMOGWdfHs97sC2OrreIxW4zkIjkQ= +git.kundeng.us/phoenix/textsender-models v0.1.6-30-f4e2336771-556/go.mod h1:9iPDQJg1Tc6WMNoW5+f8YKmnosMwlWHJ++hmxNLDEe0= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= diff --git a/internal/app/app.go b/internal/app/app.go index f2ef963..9948d51 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -1,9 +1,9 @@ package app import ( - "git.kundeng.us/phoenix/textsender-models/tx0/config" + auxcfg "git.kundeng.us/phoenix/textsender-models/tx0/config/auxiliary" ) type App struct { - TwilioConfig *config.TwilioConfig + TwilioConfig *auxcfg.TwilioConfig } diff --git a/internal/config/config.go b/internal/config/config.go index f330faa..d23f4dc 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -7,7 +7,7 @@ import ( "strconv" "strings" - "git.kundeng.us/phoenix/textsender-models/tx0/config" + auxcfg "git.kundeng.us/phoenix/textsender-models/tx0/config/auxiliary" "github.com/joho/godotenv" "git.kundeng.us/phoenix/textsender-api/internal/version" @@ -18,7 +18,7 @@ type Config struct { ServerPort string ResetDB bool JWTSecret string `env:"JWT_SECRET" required:"true"` - TwilioConfig *config.TwilioConfig + TwilioConfig *auxcfg.TwilioConfig AllowedOrigins []string } @@ -49,7 +49,7 @@ func PrintName() { fmt.Println(version.String()) } -func Load() (*Config, *config.TwilioConfig, error) { +func Load() (*Config, *auxcfg.TwilioConfig, error) { versionFlag := flag.Bool("version", false, "Print version information") resetDb := flag.Bool("reset-db", false, "Reset the database schema and exit") port := flag.String("port", PORT, "Server port") @@ -138,7 +138,7 @@ func unpackAllowedOrigins() []string { return allowedOriginsSplit } -func TwilioConfig() (*config.TwilioConfig, error) { +func TwilioConfig() (*auxcfg.TwilioConfig, error) { authSid := os.Getenv("TWILIO_AUTH_SID") serviceSid := os.Getenv("TWILIO_SERVICE_SID") authToken := os.Getenv("TWILIO_AUTH_TOKEN") @@ -153,7 +153,7 @@ func TwilioConfig() (*config.TwilioConfig, error) { } else if len(phoneNumber) == 0 { return nil, fmt.Errorf("Twilio config phone number not found") } else { - var cfg config.TwilioConfig + var cfg auxcfg.TwilioConfig cfg.AccountSID = authSid cfg.ServiceSID = serviceSid cfg.AuthToken = authToken diff --git a/internal/handler/contact_test.go b/internal/handler/contact_test.go index 1ee4388..a132d85 100644 --- a/internal/handler/contact_test.go +++ b/internal/handler/contact_test.go @@ -1,7 +1,6 @@ package handler import ( - "context" "encoding/json" "fmt" "net/http" @@ -13,7 +12,6 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" - "git.kundeng.us/phoenix/textsender-api/internal/db" "git.kundeng.us/phoenix/textsender-api/internal/handler/endpoint" "git.kundeng.us/phoenix/textsender-api/internal/store/mock" ) @@ -80,11 +78,3 @@ func TestGetContactWithMock(t *testing.T) { assert.NotNil(t, response.Data[0].Id, "Id should not be nil") } - -func resetTestDB(t *testing.T) { - t.Helper() - _, err := db.Pool.Exec(context.Background(), "DELETE FROM contacts") - if err != nil { - t.Fatalf("Failed to reset test database: %v", err) - } -} diff --git a/internal/handler/helper_test.go b/internal/handler/helper_test.go index a980d0c..4a8f190 100644 --- a/internal/handler/helper_test.go +++ b/internal/handler/helper_test.go @@ -1,14 +1,22 @@ package handler import ( + "context" "fmt" "os" "path" + "testing" + "time" + "git.kundeng.us/phoenix/textsender-models/tx0/contact" + "git.kundeng.us/phoenix/textsender-models/tx0/message" + "git.kundeng.us/phoenix/textsender-models/tx0/message/scheduling" + "github.com/google/uuid" "github.com/joho/godotenv" "git.kundeng.us/phoenix/textsender-api/internal/app" "git.kundeng.us/phoenix/textsender-api/internal/config" + "git.kundeng.us/phoenix/textsender-api/internal/db" ) func GetApp() (*app.App, error) { @@ -29,3 +37,40 @@ func GetApp() (*app.App, error) { return &app.App{TwilioConfig: tCfg}, nil } } + +func ResetTestDB(t *testing.T, tableName string) { + t.Helper() + _, err := db.Pool.Exec(context.Background(), fmt.Sprintf("DELETE FROM ", tableName)) + if err != nil { + t.Fatalf("Failed to reset test database: %v", err) + } +} + +func TestContact(id uuid.UUID, userId uuid.UUID) contact.Contact { + if id == uuid.Nil { + id = uuid.New() + return contact.Contact{Id: &id, 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, contactId, scheduledMessageId uuid.UUID) scheduling.ScheduledMessageEvent { + return scheduling.ScheduledMessageEvent{MessageId: messageId, ContactId: contactId, ScheduledMessageId: scheduledMessageId} +} diff --git a/internal/handler/message.go b/internal/handler/message.go index 8211e86..07dfa4d 100644 --- a/internal/handler/message.go +++ b/internal/handler/message.go @@ -12,16 +12,6 @@ import ( "git.kundeng.us/phoenix/textsender-api/internal/store" ) -type RequestAddMessage struct { - Content string `json:"content"` - UserId uuid.UUID `json:"user_id"` -} - -type AddMessageResponse struct { - Message string `json:"message"` - Data []message.Message `json:"data"` -} - type MessageHandler struct { App *app.App MessageStore store.MessageStore @@ -33,6 +23,16 @@ func NewMessageHandler(apiApp *app.App, str store.MessageStore) *MessageHandler const Message_Limit = 200 +type RequestAddMessage struct { + Content string `json:"content"` + UserId uuid.UUID `json:"user_id"` +} + +type AddMessageResponse struct { + Message string `json:"message"` + Data []message.Message `json:"data"` +} + // AddMessage godoc // @Summary Add message // @Description Add a message record to send a text to (requires JWT) diff --git a/internal/handler/message_event_response.go b/internal/handler/message_event_response.go index 646d613..5fc4fb4 100644 --- a/internal/handler/message_event_response.go +++ b/internal/handler/message_event_response.go @@ -72,20 +72,23 @@ func (e *EventResponseHandler) RecordResponse(w http.ResponseWriter, r *http.Req rp.Sent = *req.Sent switch req.Status { - case message.Message_Event_Response_Status_Instant: { - log.Println("Status:", req.Status) - rp.Status = req.Status - rp.MessageId = req.MessageId - rp.ContactId = req.ContactId - } - case message.Message_Event_Response_Status_Scheduled: { - log.Println("Status:", req.Status) - rp.Status = req.Status - } - default: { - statusCode = http.StatusBadRequest - resp.Message = "Status is invalid" - } + case message.Message_Event_Response_Status_Instant: + { + log.Println("Status:", req.Status) + rp.Status = req.Status + rp.MessageId = req.MessageId + rp.ContactId = req.ContactId + } + case message.Message_Event_Response_Status_Scheduled: + { + log.Println("Status:", req.Status) + rp.Status = req.Status + } + default: + { + statusCode = http.StatusBadRequest + resp.Message = "Status is invalid" + } } ctx := r.Context() @@ -103,8 +106,8 @@ func (e *EventResponseHandler) RecordResponse(w http.ResponseWriter, r *http.Req } type GetMessageEventResponseFetchedResponse struct { - Message string `json:"message"` - Data []*message.MessageEventResponse `json:"data"` + Message string `json:"message"` + Data []*message.MessageEventResponse `json:"data"` } func (e *EventResponseHandler) Fetch(w http.ResponseWriter, r *http.Request) { diff --git a/internal/handler/message_event_response_test.go b/internal/handler/message_event_response_test.go index 210099e..243b83f 100644 --- a/internal/handler/message_event_response_test.go +++ b/internal/handler/message_event_response_test.go @@ -35,9 +35,9 @@ func TestRecordMessageEventResponseWithMock(t *testing.T) { scheduledMessageId := uuid.New() testUserId := uuid.New() - con := testContact(recipientId, testUserId) - msg := testMessage(messageId, testUserId) - schMsg := testScheduledMessage(scheduledMessageId, testUserId, now) + con := TestContact(recipientId, testUserId) + msg := TestMessage(messageId, testUserId) + schMsg := TestScheduledMessage(scheduledMessageId, testUserId, now) event := scheduling.ScheduledMessageEvent{} ctx := t.Context() diff --git a/internal/handler/schedule_message_status.go b/internal/handler/schedule_message_status.go index 265f32d..f935d75 100644 --- a/internal/handler/schedule_message_status.go +++ b/internal/handler/schedule_message_status.go @@ -10,6 +10,16 @@ import ( "git.kundeng.us/phoenix/textsender-api/internal/store" ) +type ScheduledMessageStatusHandler struct { + App *app.App + ScheduledMessageEventStore store.ScheduledMessageEventStore + ScheduledMessageStore store.ScheduledMessageStore +} + +func NewScheduledMessageStatusHandler(apiApp *app.App, str store.ScheduledMessageEventStore, schStore store.ScheduledMessageStore) *ScheduledMessageStatusHandler { + return &ScheduledMessageStatusHandler{App: apiApp, ScheduledMessageEventStore: str, ScheduledMessageStore: schStore} +} + type RequestScheduledMessageStatus struct { ScheduledMessageId uuid.UUID `json:"scheduled_message_id"` Status string `json:"status"` @@ -25,16 +35,6 @@ type ScheduledMessageStatusResponse struct { Data []ScheduledMessageChange `json:"data"` } -type ScheduledMessageStatusHandler struct { - App *app.App - ScheduledMessageEventStore store.ScheduledMessageEventStore - ScheduledMessageStore store.ScheduledMessageStore -} - -func NewScheduledMessageStatusHandler(apiApp *app.App, str store.ScheduledMessageEventStore, schStore store.ScheduledMessageStore) *ScheduledMessageStatusHandler { - return &ScheduledMessageStatusHandler{App: apiApp, ScheduledMessageEventStore: str, ScheduledMessageStore: schStore} -} - // UpdateStatus godoc // @Summary Update status // @Description Update the status of a scheduled message (requires JWT) diff --git a/internal/handler/schedule_message_status_test.go b/internal/handler/schedule_message_status_test.go index 10dcbe4..0d8a2f4 100644 --- a/internal/handler/schedule_message_status_test.go +++ b/internal/handler/schedule_message_status_test.go @@ -29,10 +29,10 @@ func TestUpdateScheduledMessageStatusWithMock(t *testing.T) { scheduledMessageId := uuid.New() testUserId := uuid.New() - con := testContact(recipientId, testUserId) - msg := testMessage(messageId, testUserId) - schMsg := testScheduledMessage(scheduledMessageId, testUserId, now) - event := testScheduledMessageEvent(msg.Id, *con.Id, 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() diff --git a/internal/handler/scheduled_message.go b/internal/handler/scheduled_message.go index ba88bc1..8af8ee2 100644 --- a/internal/handler/scheduled_message.go +++ b/internal/handler/scheduled_message.go @@ -13,6 +13,15 @@ import ( "git.kundeng.us/phoenix/textsender-api/internal/store" ) +type ScheduledMessageHandler struct { + App *app.App + ScheduledMessageStore store.ScheduledMessageStore +} + +func NewScheduledMessageHandler(apiApp *app.App, str store.ScheduledMessageStore) *ScheduledMessageHandler { + return &ScheduledMessageHandler{App: apiApp, ScheduledMessageStore: str} +} + type RequestAddScheduledMessage struct { Scheduled time.Time `json:"scheduled"` Status string `json:"status"` @@ -24,25 +33,6 @@ type AddScheduledMessageResponse struct { Data []scheduling.ScheduledMessage `json:"data"` } -type GetScheduledMessageResponse struct { - Message string `json:"message"` - Data []scheduling.ScheduledMessage `json:"data"` -} - -type FetchNextMessageResponse struct { - Message string `json:"message"` - Data []scheduling.ScheduledMessage `json:"data"` -} - -type ScheduledMessageHandler struct { - App *app.App - ScheduledMessageStore store.ScheduledMessageStore -} - -func NewScheduledMessageHandler(apiApp *app.App, str store.ScheduledMessageStore) *ScheduledMessageHandler { - return &ScheduledMessageHandler{App: apiApp, ScheduledMessageStore: str} -} - // AddScheduledMessage godoc // @Summary Add scheduled message // @Description Adds a scheduled message (requires JWT) @@ -106,6 +96,11 @@ func (s *ScheduledMessageHandler) AddScheduledMessage(w http.ResponseWriter, r * RespondWithJSON(w, statusCode, &resp) } +type GetScheduledMessageResponse struct { + Message string `json:"message"` + Data []scheduling.ScheduledMessage `json:"data"` +} + // GetScheduledMessage godoc // @Summary Get scheduled message // @Description Get a scheduled message (requires JWT) @@ -183,6 +178,11 @@ func (s *ScheduledMessageHandler) GetScheduledMessage(w http.ResponseWriter, r * RespondWithJSON(w, statusCode, &resp) } +type FetchNextMessageResponse struct { + Message string `json:"message"` + Data []scheduling.ScheduledMessage `json:"data"` +} + // FetchNextMessage godoc // @Summary Fetch scheduled message // @Description Fetches a scheduled message that is available to be processed (requires JWT) diff --git a/internal/handler/scheduled_message_event.go b/internal/handler/scheduled_message_event.go index f05de6e..9c4e17e 100644 --- a/internal/handler/scheduled_message_event.go +++ b/internal/handler/scheduled_message_event.go @@ -12,27 +12,6 @@ import ( "git.kundeng.us/phoenix/textsender-api/internal/store" ) -type RequestAddScheduledMessageEvent struct { - RecipientId uuid.UUID `json:"recipient_id"` - MessageId uuid.UUID `json:"message_id"` - ScheduledMessageId uuid.UUID `json:"scheduled_message_id"` -} - -type AddScheduledMessageEventResponse struct { - Message string `json:"message"` - Data []scheduling.ScheduledMessageEvent `json:"data"` -} - -type GetScheduledMessageEventResponse struct { - Message string `json:"message"` - Data []scheduling.ScheduledMessageEvent `json:"data"` -} - -type DeleteScheduledMessageEventResponse struct { - Message string `json:"message"` - Data []scheduling.ScheduledMessageEvent `json:"data"` -} - type ScheduledMessageEventHandler struct { App *app.App ScheduledMessageEventStore store.ScheduledMessageEventStore @@ -43,7 +22,18 @@ func NewScheduledMessageEventHandler(apiApp *app.App, str store.ScheduledMessage return &ScheduledMessageEventHandler{App: apiApp, ScheduledMessageEventStore: str, ScheduledMessageStore: schStore} } -// AddContact godoc +type RequestAddScheduledMessageEvent struct { + ContactId uuid.UUID `json:"contact_id"` + MessageId uuid.UUID `json:"message_id"` + ScheduledMessageId uuid.UUID `json:"scheduled_message_id"` +} + +type AddScheduledMessageEventResponse struct { + Message string `json:"message"` + Data []scheduling.ScheduledMessageEvent `json:"data"` +} + +// AddScheduledMessageEvent godoc // @Summary Add scheduled message event // @Description Add a scheduled message event (requires JWT) // @Tags scheduled message events @@ -67,14 +57,14 @@ func (s *ScheduledMessageEventHandler) AddScheduledMessageEvent(w http.ResponseW } defer r.Body.Close() - event := scheduling.ScheduledMessageEvent{RecipientId: req.RecipientId, MessageId: req.MessageId, ScheduledMessageId: req.ScheduledMessageId} + event := scheduling.ScheduledMessageEvent{ContactId: req.ContactId, MessageId: req.MessageId, ScheduledMessageId: req.ScheduledMessageId} var statusCode int var resp AddScheduledMessageEventResponse - if event.RecipientId == uuid.Nil { + if event.ContactId == uuid.Nil { statusCode = http.StatusBadRequest - resp.Message = "Recipient Id is nil" + resp.Message = "Contact Id is nil" } else if event.MessageId == uuid.Nil { statusCode = http.StatusBadRequest resp.Message = "Message Id is nil" @@ -117,6 +107,11 @@ func (s *ScheduledMessageEventHandler) AddScheduledMessageEvent(w http.ResponseW RespondWithJSON(w, statusCode, &resp) } +type GetScheduledMessageEventResponse struct { + Message string `json:"message"` + Data []scheduling.ScheduledMessageEvent `json:"data"` +} + // GetScheduledMessageEvent godoc // @Summary Get scheduled message event // @Description Gets a scheduled message event (requires JWT) @@ -181,6 +176,11 @@ func (s *ScheduledMessageEventHandler) GetScheduledMessageEvent(w http.ResponseW RespondWithJSON(w, statusCode, &resp) } +type DeleteScheduledMessageEventResponse struct { + Message string `json:"message"` + Data []scheduling.ScheduledMessageEvent `json:"data"` +} + // DeleteScheduledMessageEvent godoc // @Summary Delete scheduled message event // @Description Deletes a scheduled message event (requires JWT) diff --git a/internal/handler/scheduled_message_event_test.go b/internal/handler/scheduled_message_event_test.go index 56fed9f..ade1517 100644 --- a/internal/handler/scheduled_message_event_test.go +++ b/internal/handler/scheduled_message_event_test.go @@ -9,8 +9,6 @@ import ( "testing" "time" - "git.kundeng.us/phoenix/textsender-models/tx0/contact" - "git.kundeng.us/phoenix/textsender-models/tx0/message" "git.kundeng.us/phoenix/textsender-models/tx0/message/scheduling" "github.com/google/uuid" "github.com/stretchr/testify/assert" @@ -20,14 +18,14 @@ import ( ) var ( - recipientId = uuid.New() + contactId = uuid.New() messageId = uuid.New() scheduledMessageId = uuid.New() testUserId = uuid.New() ) type CreateScheduledMessageEventRequest struct { - RecipientId uuid.UUID `json:"recipient_id"` + ContactId uuid.UUID `json:"recipient_id"` MessageId uuid.UUID `json:"message_id"` ScheduledMessageId uuid.UUID `json:"scheduled_message_id"` } @@ -44,14 +42,14 @@ func TestCreateScheduledMessageEventWithMock(t *testing.T) { assert.NoError(t, err, "Error getting app") handler := NewScheduledMessageEventHandler(apiApp, mockStore, schMsgStore) - recipientId := uuid.New() + contactId := uuid.New() messageId := uuid.New() scheduledMessageId := uuid.New() testUserId := uuid.New() - con := testContact(recipientId, testUserId) - msg := testMessage(messageId, testUserId) - schMsg := testScheduledMessage(scheduledMessageId, testUserId, now) + con := TestContact(contactId, testUserId) + msg := TestMessage(messageId, testUserId) + schMsg := TestScheduledMessage(scheduledMessageId, testUserId, now) ctx := t.Context() @@ -63,7 +61,7 @@ func TestCreateScheduledMessageEventWithMock(t *testing.T) { assert.NoError(t, err, "Error creating scheduled message: %v", err) } - testReq := CreateScheduledMessageEventRequest{RecipientId: recipientId, MessageId: messageId, ScheduledMessageId: scheduledMessageId} + testReq := CreateScheduledMessageEventRequest{ContactId: contactId, MessageId: messageId, ScheduledMessageId: scheduledMessageId} jsonValue, _ := json.Marshal(testReq) req, _ := http.NewRequest("POST", endpoint.AddEventToScheduledMessageEndpoint, strings.NewReader(string(jsonValue))) @@ -96,15 +94,15 @@ func TestGetScheduledMessageEventWithMock(t *testing.T) { assert.NoError(t, err, "Error getting app") handler := NewScheduledMessageEventHandler(apiApp, schMsgEventStore, schMsgStore) - recipientId := uuid.New() + contactId := uuid.New() messageId := uuid.New() scheduledMessageId := uuid.New() testUserId := uuid.New() - con := testContact(recipientId, testUserId) - msg := testMessage(messageId, testUserId) - schMsg := testScheduledMessage(scheduledMessageId, testUserId, now) - event := testScheduledMessageEvent(msg.Id, *con.Id, schMsg.Id) + con := TestContact(contactId, testUserId) + msg := TestMessage(messageId, testUserId) + schMsg := TestScheduledMessage(scheduledMessageId, testUserId, now) + event := TestScheduledMessageEvent(msg.Id, *con.Id, schMsg.Id) ctx := t.Context() @@ -147,10 +145,10 @@ func TestDeleteScheduledMessageEventWithMock(t *testing.T) { assert.NoError(t, err, "Error getting app") handler := NewScheduledMessageEventHandler(apiApp, schMsgEventStore, schMsgStore) - con := testContact(recipientId, testUserId) - msg := testMessage(messageId, testUserId) - schMsg := testScheduledMessage(scheduledMessageId, testUserId, now) - event := testScheduledMessageEvent(msg.Id, *con.Id, schMsg.Id) + con := TestContact(contactId, testUserId) + msg := TestMessage(messageId, testUserId) + schMsg := TestScheduledMessage(scheduledMessageId, testUserId, now) + event := TestScheduledMessageEvent(msg.Id, *con.Id, schMsg.Id) ctx := t.Context() @@ -182,32 +180,3 @@ func TestDeleteScheduledMessageEventWithMock(t *testing.T) { 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 { - id = uuid.New() - return contact.Contact{Id: &id, 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} -} diff --git a/internal/handler/scheduled_message_test.go b/internal/handler/scheduled_message_test.go index b3ca5c3..60ce7dd 100644 --- a/internal/handler/scheduled_message_test.go +++ b/internal/handler/scheduled_message_test.go @@ -89,15 +89,15 @@ func TestFetchScheduledMessageWithMock(t *testing.T) { messageStore := mock.NewMockMessageStore() schMsgEventStore := mock.NewMockScheduledMessageEventStore() - recipientId := uuid.New() + contactId := uuid.New() messageId := uuid.New() scheduledMessageId := uuid.New() testUserId := uuid.New() - con := testContact(recipientId, testUserId) - msg := testMessage(messageId, testUserId) - schMsg := testScheduledMessage(scheduledMessageId, testUserId, now) - event := testScheduledMessageEvent(msg.Id, *con.Id, schMsg.Id) + con := TestContact(contactId, testUserId) + msg := TestMessage(messageId, testUserId) + schMsg := TestScheduledMessage(scheduledMessageId, testUserId, now) + event := TestScheduledMessageEvent(msg.Id, *con.Id, schMsg.Id) ctx := t.Context() diff --git a/internal/store/message_event_response_store.go b/internal/store/message_event_response_store.go index ad0300e..2a9f4de 100644 --- a/internal/store/message_event_response_store.go +++ b/internal/store/message_event_response_store.go @@ -4,14 +4,14 @@ import ( "context" "fmt" - "git.kundeng.us/phoenix/textsender-models/tx0/message" + "git.kundeng.us/phoenix/textsender-models/tx0/message/event" "github.com/google/uuid" "github.com/jackc/pgx/v5/pgxpool" ) type MessageEventResponseStore interface { - Create(ctx context.Context, mer *message.MessageEventResponse) error - GetWithUserId(ctx context.Context, userId uuid.UUID) ([]*message.MessageEventResponse, error) + Create(ctx context.Context, mer *event.MessageEventResponse) error + GetWithUserId(ctx context.Context, userId uuid.UUID) ([]*event.MessageEventResponse, error) } type PGMessageEventResponseStore struct { @@ -22,7 +22,7 @@ func NewMessageEventResponseStore(db *pgxpool.Pool) *PGMessageEventResponseStore return &PGMessageEventResponseStore{db: db} } -func (m *PGMessageEventResponseStore) Create(ctx context.Context, mer *message.MessageEventResponse) error { +func (m *PGMessageEventResponseStore) Create(ctx context.Context, mer *event.MessageEventResponse) error { var query string queryBase := "INSERT INTO message_event_responses" queryReturn := "RETURNING id" @@ -32,11 +32,11 @@ func (m *PGMessageEventResponseStore) Create(ctx context.Context, mer *message.M return m.db.QueryRow(ctx, query, mer.Response, mer.UserId, mer.Sent, mer.ContactId, mer.MessageId, mer.Status).Scan(&mer.Id) } else { query = fmt.Sprintf("%s (scheduled_message_event_id, response, user_id, sent, contact_id, message_id, status) VALUES ($1, $2, $3, $4, $5, $6, $7) %s", queryBase, queryReturn) - return m.db.QueryRow(ctx, query, mer.ScheduledMessageEventId, mer.Response, mer.UserId, mer.Sent, mer.ContactId, mer.MessageId, mer.Status,).Scan(&mer.Id) + return m.db.QueryRow(ctx, query, mer.ScheduledMessageEventId, mer.Response, mer.UserId, mer.Sent, mer.ContactId, mer.MessageId, mer.Status).Scan(&mer.Id) } } -func (m *PGMessageEventResponseStore) GetWithUserId(ctx context.Context, userId uuid.UUID) ([]*message.MessageEventResponse, error) { +func (m *PGMessageEventResponseStore) GetWithUserId(ctx context.Context, userId uuid.UUID) ([]*event.MessageEventResponse, error) { query := "SELECT id, scheduled_message_event_id, response, user_id, sent, contact_id, message_id, status FROM message_event_responses WHERE user_id = $1" rows, err := m.db.Query(ctx, query) if err != nil { @@ -44,10 +44,10 @@ func (m *PGMessageEventResponseStore) GetWithUserId(ctx context.Context, userId } defer rows.Close() - var sentMessages []*message.MessageEventResponse + var sentMessages []*event.MessageEventResponse for rows.Next() { - var msg message.MessageEventResponse - if err := rows.Scan(&msg.Id, &msg.ScheduledMessageEventId, &msg.Response, &msg.UserId, &msg.Sent, &msg.ContactId, &msg.MessageId, &msg.Status,); err != nil { + var msg event.MessageEventResponse + if err := rows.Scan(&msg.Id, &msg.ScheduledMessageEventId, &msg.Response, &msg.UserId, &msg.Sent, &msg.ContactId, &msg.MessageId, &msg.Status); err != nil { return nil, fmt.Errorf("Scanning row: %w", err) } sentMessages = append(sentMessages, &msg) diff --git a/internal/store/mock/message_event_response_store.go b/internal/store/mock/message_event_response_store.go index ee3d668..5ffc0ff 100644 --- a/internal/store/mock/message_event_response_store.go +++ b/internal/store/mock/message_event_response_store.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "git.kundeng.us/phoenix/textsender-models/tx0/message" + "git.kundeng.us/phoenix/textsender-models/tx0/message/event" "github.com/google/uuid" ) @@ -15,20 +15,20 @@ type MessageEventResponseKey struct { UserId uuid.UUID } type MockMessageEventResponseStore struct { - MessageEventResponses map[uuid.UUID]*message.MessageEventResponse - MessageEventResponsesByKey map[MessageEventResponseKey]*message.MessageEventResponse + MessageEventResponses map[uuid.UUID]*event.MessageEventResponse + MessageEventResponsesByKey map[MessageEventResponseKey]*event.MessageEventResponse mu sync.RWMutex Error error } func NewMockMessageEventResponseStore() *MockMessageEventResponseStore { return &MockMessageEventResponseStore{ - MessageEventResponses: make(map[uuid.UUID]*message.MessageEventResponse), - MessageEventResponsesByKey: make(map[MessageEventResponseKey]*message.MessageEventResponse), + MessageEventResponses: make(map[uuid.UUID]*event.MessageEventResponse), + MessageEventResponsesByKey: make(map[MessageEventResponseKey]*event.MessageEventResponse), } } -func (m *MockMessageEventResponseStore) Create(ctx context.Context, mer *message.MessageEventResponse) error { +func (m *MockMessageEventResponseStore) Create(ctx context.Context, mer *event.MessageEventResponse) error { m.mu.Lock() defer m.mu.Unlock() @@ -62,7 +62,7 @@ func (m *MockMessageEventResponseStore) Create(ctx context.Context, mer *message } // TODO: Add code to get mock MessageEventResponse -func (m *MockMessageEventResponseStore) GetWithUserId(ctx context.Context, userId uuid.UUID) ([]*message.MessageEventResponse, error) { +func (m *MockMessageEventResponseStore) GetWithUserId(ctx context.Context, userId uuid.UUID) ([]*event.MessageEventResponse, error) { m.mu.Lock() defer m.mu.Unlock() @@ -70,13 +70,12 @@ func (m *MockMessageEventResponseStore) GetWithUserId(ctx context.Context, userI return nil, m.Error } - var messages []*message.MessageEventResponse + var messages []*event.MessageEventResponse for _, msg := range m.MessageEventResponses { if msg.UserId == userId { messages = append(messages, msg) } } - return messages, nil } diff --git a/internal/store/scheduled_message_event_store.go b/internal/store/scheduled_message_event_store.go index e17fc7e..ae27c50 100644 --- a/internal/store/scheduled_message_event_store.go +++ b/internal/store/scheduled_message_event_store.go @@ -27,11 +27,11 @@ func NewScheduledMessageEventStore(db *pgxpool.Pool) *PGScheduledMessageEventSto } func (s *PGScheduledMessageEventStore) Get(ctx context.Context, id uuid.UUID) (*scheduling.ScheduledMessageEvent, error) { - query := `SELECT id, recipient_id, message_id, scheduled_message_id, created FROM scheduled_message_events WHERE id = $1` + query := `SELECT id, contact_id, message_id, scheduled_message_id, created FROM scheduled_message_events WHERE id = $1` var event scheduling.ScheduledMessageEvent err := s.db.QueryRow(ctx, query, id).Scan( - &event.Id, &event.RecipientId, &event.MessageId, &event.ScheduledMessageId, &event.Created, + &event.Id, &event.ContactId, &event.MessageId, &event.ScheduledMessageId, &event.Created, ) if err == pgx.ErrNoRows { @@ -45,7 +45,7 @@ func (s *PGScheduledMessageEventStore) Get(ctx context.Context, id uuid.UUID) (* func (s *PGScheduledMessageEventStore) GetWithScheduleMessageId(ctx context.Context, schMsgId uuid.UUID) ([]*scheduling.ScheduledMessageEvent, error) { var events []*scheduling.ScheduledMessageEvent - query := `SELECT id, recipient_id, message_id, scheduled_message_id, created FROM scheduled_message_events WHERE scheduled_message_id = $1 + query := `SELECT id, contact_id, message_id, scheduled_message_id, created FROM scheduled_message_events WHERE scheduled_message_id = $1 ` rows, err := s.db.Query(ctx, query, schMsgId) @@ -57,7 +57,7 @@ func (s *PGScheduledMessageEventStore) GetWithScheduleMessageId(ctx context.Cont for rows.Next() { var event scheduling.ScheduledMessageEvent - if err := rows.Scan(&event.Id, &event.RecipientId, &event.MessageId, &event.ScheduledMessageId, &event.Created); err != nil { + if err := rows.Scan(&event.Id, &event.ContactId, &event.MessageId, &event.ScheduledMessageId, &event.Created); err != nil { return nil, fmt.Errorf("Error fetching data from row: %w", err) } else { events = append(events, &event) @@ -90,21 +90,21 @@ func (s *PGScheduledMessageEventStore) Delete(ctx context.Context, id uuid.UUID) func (s *PGScheduledMessageEventStore) CreateScheduledMessageEvent(ctx context.Context, event *scheduling.ScheduledMessageEvent) error { query := ` - INSERT INTO scheduled_message_events (recipient_id, message_id, scheduled_message_id) + INSERT INTO scheduled_message_events (contact_id, message_id, scheduled_message_id) VALUES ($1, $2, $3) RETURNING id, created ` - return s.db.QueryRow(ctx, query, event.RecipientId, event.MessageId, event.ScheduledMessageId).Scan( + return s.db.QueryRow(ctx, query, event.ContactId, event.MessageId, event.ScheduledMessageId).Scan( &event.Id, &event.Created, ) } func (s *PGScheduledMessageEventStore) Exists(ctx context.Context, event *scheduling.ScheduledMessageEvent) (bool, error) { - query := `SELECT EXISTS(SELECT 1 FROM scheduled_message_events WHERE scheduled_message_id = $1 AND recipient_id = $2)` + query := `SELECT EXISTS(SELECT 1 FROM scheduled_message_events WHERE scheduled_message_id = $1 AND contact_id = $2)` var exists bool - err := s.db.QueryRow(ctx, query, event.ScheduledMessageId, event.RecipientId).Scan(&exists) + err := s.db.QueryRow(ctx, query, event.ScheduledMessageId, event.ContactId).Scan(&exists) if err != nil { return false, fmt.Errorf("Scheduled message event does not exist: %w", err) } else { diff --git a/migrations/schema.sql b/migrations/schema.sql index f7a8a1a..b8d3401 100644 --- a/migrations/schema.sql +++ b/migrations/schema.sql @@ -28,7 +28,7 @@ CREATE TABLE IF NOT EXISTS scheduled_messages ( CREATE TABLE IF NOT EXISTS scheduled_message_events ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), - recipient_id UUID NOT NULL, + contact_id UUID NOT NULL, message_id UUID NOT NULL, scheduled_message_id UUID NOT NULL, created timestamptz DEFAULT now()