diff --git a/docs/docs.go b/docs/docs.go index 39cbb99..a5cbb4c 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -490,6 +490,106 @@ const docTemplate = `{ } } }, + "/schedule/message/event/response": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Fetches a MessageEventResponse given a user id (requires JWT)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Fetcht MessageEventResponse", + "parameters": [ + { + "type": "string", + "description": "User Id", + "name": "user_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.GetMessageEventResponseFetchedResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/handler.GetMessageEventResponseFetchedResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/handler.GetMessageEventResponseFetchedResponse" + } + } + } + } + }, + "/schedule/message/event/response/record": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Saves the result of sending a text message (requires JWT)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Record MessageEventResponse", + "parameters": [ + { + "description": "Data to add MessageEventResponse", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handler.RecordEventRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/handler.RecordEventResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/handler.RecordEventResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/handler.RecordEventResponse" + } + } + } + } + }, "/schedule/message/event/{id}": { "delete": { "security": [ @@ -642,9 +742,18 @@ const docTemplate = `{ "contact.Contact": { "type": "object", "properties": { + "first_name": { + "type": "string" + }, "id": { "type": "string" }, + "last_name": { + "type": "string" + }, + "nickname": { + "type": "string" + }, "phone_number": { "type": "string" }, @@ -653,6 +762,36 @@ const docTemplate = `{ } } }, + "event.MessageEventResponse": { + "type": "object", + "properties": { + "contact_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "message_id": { + "type": "string" + }, + "response": { + "type": "object", + "additionalProperties": {} + }, + "scheduled_message_event_id": { + "type": "string" + }, + "sent": { + "type": "string" + }, + "status": { + "type": "string" + }, + "user_id": { + "type": "string" + } + } + }, "handler.AddContactResponse": { "type": "object", "properties": { @@ -751,6 +890,20 @@ const docTemplate = `{ } } }, + "handler.GetMessageEventResponseFetchedResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/event.MessageEventResponse" + } + }, + "message": { + "type": "string" + } + } + }, "handler.GetMessageResponse": { "type": "object", "properties": { @@ -793,6 +946,47 @@ const docTemplate = `{ } } }, + "handler.RecordEventRequest": { + "type": "object", + "properties": { + "contact_id": { + "type": "string" + }, + "message_id": { + "type": "string" + }, + "response": { + "type": "object", + "additionalProperties": {} + }, + "scheduled_message_event_id": { + "type": "string" + }, + "sent": { + "type": "string" + }, + "status": { + "type": "string" + }, + "user_id": { + "type": "string" + } + } + }, + "handler.RecordEventResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/event.MessageEventResponse" + } + }, + "message": { + "type": "string" + } + } + }, "handler.RequestAddContact": { "type": "object", "properties": { @@ -832,10 +1026,10 @@ const docTemplate = `{ "handler.RequestAddScheduledMessageEvent": { "type": "object", "properties": { - "message_id": { + "contact_id": { "type": "string" }, - "recipient_id": { + "message_id": { "type": "string" }, "scheduled_message_id": { @@ -902,7 +1096,7 @@ const docTemplate = `{ "data": { "type": "array", "items": { - "$ref": "#/definitions/message.MessageEventResponse" + "$ref": "#/definitions/event.MessageEventResponse" } }, "message": { @@ -924,29 +1118,6 @@ const docTemplate = `{ } } }, - "message.MessageEventResponse": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "response": { - "type": "array", - "items": { - "type": "integer" - } - }, - "scheduled_message_event_id": { - "type": "string" - }, - "sent": { - "type": "string" - }, - "user_id": { - "type": "string" - } - } - }, "scheduling.ScheduledMessage": { "type": "object", "properties": { @@ -970,6 +1141,9 @@ const docTemplate = `{ "scheduling.ScheduledMessageEvent": { "type": "object", "properties": { + "contact_id": { + "type": "string" + }, "created": { "type": "string" }, @@ -979,9 +1153,6 @@ const docTemplate = `{ "message_id": { "type": "string" }, - "recipient_id": { - "type": "string" - }, "scheduled_message_id": { "type": "string" } diff --git a/docs/swagger.json b/docs/swagger.json index 7dddc2b..52f8d48 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -484,6 +484,106 @@ } } }, + "/schedule/message/event/response": { + "get": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Fetches a MessageEventResponse given a user id (requires JWT)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Fetcht MessageEventResponse", + "parameters": [ + { + "type": "string", + "description": "User Id", + "name": "user_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/handler.GetMessageEventResponseFetchedResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/handler.GetMessageEventResponseFetchedResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/handler.GetMessageEventResponseFetchedResponse" + } + } + } + } + }, + "/schedule/message/event/response/record": { + "post": { + "security": [ + { + "BearerAuth": [] + } + ], + "description": "Saves the result of sending a text message (requires JWT)", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "message" + ], + "summary": "Record MessageEventResponse", + "parameters": [ + { + "description": "Data to add MessageEventResponse", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/handler.RecordEventRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/handler.RecordEventResponse" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/handler.RecordEventResponse" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/handler.RecordEventResponse" + } + } + } + } + }, "/schedule/message/event/{id}": { "delete": { "security": [ @@ -636,9 +736,18 @@ "contact.Contact": { "type": "object", "properties": { + "first_name": { + "type": "string" + }, "id": { "type": "string" }, + "last_name": { + "type": "string" + }, + "nickname": { + "type": "string" + }, "phone_number": { "type": "string" }, @@ -647,6 +756,36 @@ } } }, + "event.MessageEventResponse": { + "type": "object", + "properties": { + "contact_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "message_id": { + "type": "string" + }, + "response": { + "type": "object", + "additionalProperties": {} + }, + "scheduled_message_event_id": { + "type": "string" + }, + "sent": { + "type": "string" + }, + "status": { + "type": "string" + }, + "user_id": { + "type": "string" + } + } + }, "handler.AddContactResponse": { "type": "object", "properties": { @@ -745,6 +884,20 @@ } } }, + "handler.GetMessageEventResponseFetchedResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/event.MessageEventResponse" + } + }, + "message": { + "type": "string" + } + } + }, "handler.GetMessageResponse": { "type": "object", "properties": { @@ -787,6 +940,47 @@ } } }, + "handler.RecordEventRequest": { + "type": "object", + "properties": { + "contact_id": { + "type": "string" + }, + "message_id": { + "type": "string" + }, + "response": { + "type": "object", + "additionalProperties": {} + }, + "scheduled_message_event_id": { + "type": "string" + }, + "sent": { + "type": "string" + }, + "status": { + "type": "string" + }, + "user_id": { + "type": "string" + } + } + }, + "handler.RecordEventResponse": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/event.MessageEventResponse" + } + }, + "message": { + "type": "string" + } + } + }, "handler.RequestAddContact": { "type": "object", "properties": { @@ -826,10 +1020,10 @@ "handler.RequestAddScheduledMessageEvent": { "type": "object", "properties": { - "message_id": { + "contact_id": { "type": "string" }, - "recipient_id": { + "message_id": { "type": "string" }, "scheduled_message_id": { @@ -896,7 +1090,7 @@ "data": { "type": "array", "items": { - "$ref": "#/definitions/message.MessageEventResponse" + "$ref": "#/definitions/event.MessageEventResponse" } }, "message": { @@ -918,29 +1112,6 @@ } } }, - "message.MessageEventResponse": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "response": { - "type": "array", - "items": { - "type": "integer" - } - }, - "scheduled_message_event_id": { - "type": "string" - }, - "sent": { - "type": "string" - }, - "user_id": { - "type": "string" - } - } - }, "scheduling.ScheduledMessage": { "type": "object", "properties": { @@ -964,6 +1135,9 @@ "scheduling.ScheduledMessageEvent": { "type": "object", "properties": { + "contact_id": { + "type": "string" + }, "created": { "type": "string" }, @@ -973,9 +1147,6 @@ "message_id": { "type": "string" }, - "recipient_id": { - "type": "string" - }, "scheduled_message_id": { "type": "string" } diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 9c5f966..6ebfb30 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -2,13 +2,39 @@ basePath: /api/v1 definitions: contact.Contact: properties: + first_name: + type: string id: type: string + last_name: + type: string + nickname: + type: string phone_number: type: string user_id: type: string type: object + event.MessageEventResponse: + properties: + contact_id: + type: string + id: + type: string + message_id: + type: string + response: + additionalProperties: {} + type: object + scheduled_message_event_id: + type: string + sent: + type: string + status: + type: string + user_id: + type: string + type: object handler.AddContactResponse: properties: data: @@ -72,6 +98,15 @@ definitions: message: type: string type: object + handler.GetMessageEventResponseFetchedResponse: + properties: + data: + items: + $ref: '#/definitions/event.MessageEventResponse' + type: array + message: + type: string + type: object handler.GetMessageResponse: properties: data: @@ -99,6 +134,33 @@ definitions: message: type: string type: object + handler.RecordEventRequest: + properties: + contact_id: + type: string + message_id: + type: string + response: + additionalProperties: {} + type: object + scheduled_message_event_id: + type: string + sent: + type: string + status: + type: string + user_id: + type: string + type: object + handler.RecordEventResponse: + properties: + data: + items: + $ref: '#/definitions/event.MessageEventResponse' + type: array + message: + type: string + type: object handler.RequestAddContact: properties: phone_number: @@ -124,9 +186,9 @@ definitions: type: object handler.RequestAddScheduledMessageEvent: properties: - message_id: + contact_id: type: string - recipient_id: + message_id: type: string scheduled_message_id: type: string @@ -169,7 +231,7 @@ definitions: properties: data: items: - $ref: '#/definitions/message.MessageEventResponse' + $ref: '#/definitions/event.MessageEventResponse' type: array message: type: string @@ -183,21 +245,6 @@ definitions: user_id: type: string type: object - message.MessageEventResponse: - properties: - id: - type: string - response: - items: - type: integer - type: array - scheduled_message_event_id: - type: string - sent: - type: string - user_id: - type: string - type: object scheduling.ScheduledMessage: properties: created: @@ -213,14 +260,14 @@ definitions: type: object scheduling.ScheduledMessageEvent: properties: + contact_id: + type: string created: type: string id: type: string message_id: type: string - recipient_id: - type: string scheduled_message_id: type: string type: object @@ -569,6 +616,69 @@ paths: summary: Delete scheduled message event tags: - scheduled message events + /schedule/message/event/response: + get: + consumes: + - application/json + description: Fetches a MessageEventResponse given a user id (requires JWT) + parameters: + - description: User Id + in: path + name: user_id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/handler.GetMessageEventResponseFetchedResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/handler.GetMessageEventResponseFetchedResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/handler.GetMessageEventResponseFetchedResponse' + security: + - BearerAuth: [] + summary: Fetcht MessageEventResponse + tags: + - message + /schedule/message/event/response/record: + post: + consumes: + - application/json + description: Saves the result of sending a text message (requires JWT) + parameters: + - description: Data to add MessageEventResponse + in: body + name: request + required: true + schema: + $ref: '#/definitions/handler.RecordEventRequest' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/handler.RecordEventResponse' + "400": + description: Bad Request + schema: + $ref: '#/definitions/handler.RecordEventResponse' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/handler.RecordEventResponse' + security: + - BearerAuth: [] + summary: Record MessageEventResponse + tags: + - message /schedule/message/fetch: get: consumes: diff --git a/internal/handler/endpoint/endpoint.go b/internal/handler/endpoint/endpoint.go index c6bda68..1c3676d 100644 --- a/internal/handler/endpoint/endpoint.go +++ b/internal/handler/endpoint/endpoint.go @@ -1,19 +1,28 @@ package endpoint -const MESSAGE_DRAFT_ENDPOINT = "/api/v1/message/draft" -const ADD_MESSAGE = "/api/v1/message/new" -const GET_MESSAGE = "/api/v1/message" -const GET_CONTACT = "/api/v1/contact" -const ADD_CONTACT_ENDPOINT = "/api/v1/contact/new" -const ScheduleMessageEndpoint = "/api/v1/schedule/message" -const GetScheduledMessageEndpoint = "/api/v1/schedule/message" -const AddEventToScheduledMessageEndpoint = "/api/v1/schedule/message/event" -const GetScheduledMessageEventEndpoint = "/api/v1/schedule/message/event" -const DeleteScheduledMessageEventEndpoint = "/api/v1/schedule/message/event/{id}" -const UpdateScheduledMessageStatusEndpoint = "/api/v1/schedule/message/status/update" -const FetchNextScheduledMessageEndpoint = "/api/v1/schedule/message/fetch" -// TODO: Tweak endpoint verbage for MessageEventResponse endpoint -// TODO: Make RecordEventResponse more consistent with MessageEventResponse -const RecordEventResponse = "/api/v1/schedule/message/event/response/record" -const FetchMessageEventResponse = "/api/v1/schedule/message/event/response" -const SendInstantMessageEndpoint = "/api/v1/instant/message" +const ( + MESSAGE_DRAFT_ENDPOINT = "/api/v1/message/draft" + + ADD_MESSAGE = "/api/v1/message/new" + GET_MESSAGE = "/api/v1/message" + + GET_CONTACT = "/api/v1/contact" + ADD_CONTACT_ENDPOINT = "/api/v1/contact/new" + + ScheduleMessageEndpoint = "/api/v1/schedule/message" + GetScheduledMessageEndpoint = "/api/v1/schedule/message" + + AddEventToScheduledMessageEndpoint = "/api/v1/schedule/message/event" + GetScheduledMessageEventEndpoint = "/api/v1/schedule/message/event" + DeleteScheduledMessageEventEndpoint = "/api/v1/schedule/message/event/{id}" + UpdateScheduledMessageStatusEndpoint = "/api/v1/schedule/message/status/update" + + FetchNextScheduledMessageEndpoint = "/api/v1/schedule/message/fetch" + + // TODO: Tweak endpoint verbage for MessageEventResponse endpoint + // TODO: Make RecordEventResponse more consistent with MessageEventResponse + RecordEventResponse = "/api/v1/schedule/message/event/response/record" + FetchMessageEventResponse = "/api/v1/schedule/message/event/response" + + SendInstantMessageEndpoint = "/api/v1/instant/message" +) diff --git a/internal/handler/helper_test.go b/internal/handler/helper_test.go index 4a8f190..4c4c656 100644 --- a/internal/handler/helper_test.go +++ b/internal/handler/helper_test.go @@ -2,6 +2,7 @@ package handler import ( "context" + "encoding/json" "fmt" "os" "path" @@ -74,3 +75,36 @@ func TestScheduledMessage(id uuid.UUID, userId uuid.UUID, now time.Time) schedul func TestScheduledMessageEvent(messageId, contactId, scheduledMessageId uuid.UUID) scheduling.ScheduledMessageEvent { return scheduling.ScheduledMessageEvent{MessageId: messageId, ContactId: contactId, ScheduledMessageId: scheduledMessageId} } + +func TestMERResponseInString() string { + return `{ + "body": "Whoknows?", + "num_segments": "0", + "direction": "outbound-api", + "from": "+12243026041", + "to": "+16303831708", + "date_updated": "Sat,29Nov202519:06:59+0000", + "uri": "/2010-04-01/Accounts/ACefa1ef516314c9d1a68cbd657de49277/Messages/SM1193a529e7f7a840667cd1e0f13ea95a.json", + "account_sid": "ACefa1ef516314c9d1a68cbd657de49277", + "num_media": "0", + "status": "scheduled", + "messaging_service_sid": "MG803f3676706b92eb02e18dd820c447f2", + "sid": "SM1193a529e7f7a840667cd1e0f13ea95a", + "date_created": "Sat,29Nov202519:06:59+0000", + "api_version": "2010-04-01", + "subresource_uris": { + "media": "/2010-04-01/Accounts/ACefa1ef516314c9d1a68cbd657de49277/Messages/SM1193a529e7f7a840667cd1e0f13ea95a/Media.json" + } +}` +} + +func TestConvertStringToMapOfAny(response string) (map[string]any, error) { + bytes := []byte(response) + var merResponse map[string]any + err := json.Unmarshal(bytes, &merResponse) + if err != nil { + return nil, err + } else { + return merResponse, nil + } +} diff --git a/internal/handler/message_event_response.go b/internal/handler/message_event_response.go index 9092602..7dc00ac 100644 --- a/internal/handler/message_event_response.go +++ b/internal/handler/message_event_response.go @@ -36,6 +36,18 @@ type RecordEventResponse struct { Data []*event.MessageEventResponse `json:"data"` } +// RecordMessageEventResponse godoc +// @Summary Record MessageEventResponse +// @Description Saves the result of sending a text message (requires JWT) +// @Tags message +// @Accept json +// @Produce json +// @Security BearerAuth +// @Param request body RecordEventRequest true "Data to add MessageEventResponse" +// @Success 201 {object} RecordEventResponse +// @Failure 400 {object} RecordEventResponse +// @Failure 500 {object} RecordEventResponse +// @Router /schedule/message/event/response/record [post] func (e *EventResponseHandler) RecordResponse(w http.ResponseWriter, r *http.Request) { var req RecordEventRequest if err := ExtractFromRequest(r, &req); err != nil { @@ -107,6 +119,18 @@ type GetMessageEventResponseFetchedResponse struct { Data []*event.MessageEventResponse `json:"data"` } +// FetchtMessageEventResponse godoc +// @Summary Fetcht MessageEventResponse +// @Description Fetches a MessageEventResponse given a user id (requires JWT) +// @Tags message +// @Accept json +// @Produce json +// @Param user_id path string true "User Id" +// @Security BearerAuth +// @Success 200 {object} GetMessageEventResponseFetchedResponse +// @Failure 400 {object} GetMessageEventResponseFetchedResponse +// @Failure 500 {object} GetMessageEventResponseFetchedResponse +// @Router /schedule/message/event/response [get] func (e *EventResponseHandler) Fetch(w http.ResponseWriter, r *http.Request) { queryParams := r.URL.Query() var userId uuid.UUID diff --git a/internal/handler/message_event_response_test.go b/internal/handler/message_event_response_test.go index 243b83f..b6e48ba 100644 --- a/internal/handler/message_event_response_test.go +++ b/internal/handler/message_event_response_test.go @@ -2,13 +2,14 @@ package handler import ( "encoding/json" + "fmt" "net/http" "net/http/httptest" "strings" "testing" "time" - "git.kundeng.us/phoenix/textsender-models/tx0/message" + evnt "git.kundeng.us/phoenix/textsender-models/tx0/message/event" "git.kundeng.us/phoenix/textsender-models/tx0/message/scheduling" "github.com/google/uuid" "github.com/stretchr/testify/assert" @@ -30,12 +31,12 @@ func TestRecordMessageEventResponseWithMock(t *testing.T) { assert.NoError(t, err, "Error getting app") handler := NewEventResponseHandler(apiApp, merStore) - recipientId := uuid.New() + contactId := uuid.New() messageId := uuid.New() scheduledMessageId := uuid.New() testUserId := uuid.New() - con := TestContact(recipientId, testUserId) + con := TestContact(contactId, testUserId) msg := TestMessage(messageId, testUserId) schMsg := TestScheduledMessage(scheduledMessageId, testUserId, now) event := scheduling.ScheduledMessageEvent{} @@ -50,17 +51,19 @@ func TestRecordMessageEventResponseWithMock(t *testing.T) { assert.NoError(t, err, "Error creating scheduled message: %v", err) } - event.MessageId = msg.Id - event.RecipientId = *con.Id + event.MessageId = *msg.Id + event.ContactId = *con.Id event.ScheduledMessageId = schMsg.Id if err := mockStore.CreateScheduledMessageEvent(ctx, &event); err != nil { assert.NoError(t, err, "Error creating scheduled message event: %v", err) } sent := now.Add(30 * time.Minute) - bytes := []byte("{\"body\":\"Whoknows?\",\"num_segments\":\"0\",\"direction\":\"outbound-api\",\"from\":\"+12243026041\",\"to\":\"+16303831708\",\"date_updated\":\"Sat,29Nov202519:06:59+0000\",\"uri\":\"/2010-04-01/Accounts/ACefa1ef516314c9d1a68cbd657de49277/Messages/SM1193a529e7f7a840667cd1e0f13ea95a.json\",\"account_sid\":\"ACefa1ef516314c9d1a68cbd657de49277\",\"num_media\":\"0\",\"status\":\"scheduled\",\"messaging_service_sid\":\"MG803f3676706b92eb02e18dd820c447f2\",\"sid\":\"SM1193a529e7f7a840667cd1e0f13ea95a\",\"date_created\":\"Sat,29Nov202519:06:59+0000\",\"api_version\":\"2010-04-01\",\"subresource_uris\":{\"media\":\"/2010-04-01/Accounts/ACefa1ef516314c9d1a68cbd657de49277/Messages/SM1193a529e7f7a840667cd1e0f13ea95a/Media.json\"}}") + var merResponse map[string]any + merResponse, err = TestConvertStringToMapOfAny(TestMERResponseInString()) + assert.NoError(t, err, "Error Converting to map[string]any") - testReq := RecordEventRequest{ScheduledMessageEventId: event.Id, Response: bytes, UserId: schMsg.UserId, Sent: &sent, Status: message.Message_Event_Response_Status_Scheduled} + testReq := RecordEventRequest{ScheduledMessageEventId: event.Id, Response: merResponse, UserId: schMsg.UserId, Sent: &sent, Status: evnt.Message_Event_Response_Status_Scheduled} jsonValue, _ := json.Marshal(testReq) req, _ := http.NewRequest("POST", endpoint.RecordEventResponse, strings.NewReader(string(jsonValue))) @@ -76,9 +79,84 @@ func TestRecordMessageEventResponseWithMock(t *testing.T) { assert.NotEmpty(t, response.Data, "No message event response created") - var msgEventResp message.MessageEventResponse + var msgEventResp evnt.MessageEventResponse msgEventResp = *response.Data[0] assert.NotEmpty(t, msgEventResp.Response, "The response of the message event response is empty") assert.Equal(t, msgEventResp.Response, testReq.Response, "Responses do not match") } + +func TestGetMessageEventResponse(t *testing.T) { + now := time.Now() + + mockStore := mock.NewMockScheduledMessageEventStore() + contactStore := mock.NewMockContactStore() + messageStore := mock.NewMockMessageStore() + schMsgStore := mock.NewMockScheduledMessageStore() + merStore := mock.NewMockMessageEventResponseStore() + + apiApp, err := GetApp() + assert.NoError(t, err, "Error getting app") + handler := NewEventResponseHandler(apiApp, merStore) + + contactId := uuid.New() + messageId := uuid.New() + scheduledMessageId := uuid.New() + testUserId := uuid.New() + + con := TestContact(contactId, testUserId) + msg := TestMessage(messageId, testUserId) + schMsg := TestScheduledMessage(scheduledMessageId, testUserId, now) + event := scheduling.ScheduledMessageEvent{} + + 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) + } + + event.MessageId = *msg.Id + event.ContactId = *con.Id + event.ScheduledMessageId = schMsg.Id + sent := now.Add(30 * time.Minute) + if err := mockStore.CreateScheduledMessageEvent(ctx, &event); err != nil { + assert.NoError(t, err, "Error creating scheduled message event: %v", err) + } else { + m := evnt.MessageEventResponse{} + m.ScheduledMessageEventId = event.Id + m.UserId = schMsg.UserId + m.Status = evnt.Message_Event_Response_Status_Scheduled + m.Sent = sent + var merResponse map[string]any + merResponse, err = TestConvertStringToMapOfAny(TestMERResponseInString()) + assert.NoError(t, err, "Error Converting to map[string]any") + m.Response = merResponse + + if err := merStore.Create(ctx, &m); err != nil { + assert.NoError(t, err, "Error creating MessageEventResponse: %v", err) + } + } + + url := fmt.Sprintf("%s?user_id=%s", endpoint.FetchMessageEventResponse, testUserId.String()) + req, _ := http.NewRequest("GET", url, nil) + rr := httptest.NewRecorder() + + handler.RecordResponse(rr, req) + + assert.Equal(t, http.StatusOK, rr.Code) + + var response GetMessageEventResponseFetchedResponse + err = json.Unmarshal(rr.Body.Bytes(), &response) + assert.NoError(t, err, "Error parsing message event response: %v", err) + + assert.NotEmpty(t, response.Data, "No message event response found") + + var msgEventResp evnt.MessageEventResponse + msgEventResp = *response.Data[0] + + assert.NotEmpty(t, msgEventResp.Response, "The response of the message event response is empty") +} diff --git a/internal/store/message_event_response_store.go b/internal/store/message_event_response_store.go index 2a9f4de..4cf0a19 100644 --- a/internal/store/message_event_response_store.go +++ b/internal/store/message_event_response_store.go @@ -38,7 +38,7 @@ func (m *PGMessageEventResponseStore) Create(ctx context.Context, mer *event.Mes 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) + rows, err := m.db.Query(ctx, query, userId) if err != nil { return nil, fmt.Errorf("Error querying: %w", err) } diff --git a/internal/store/mock/scheduled_message_event_store.go b/internal/store/mock/scheduled_message_event_store.go index b7b3cf8..f8631f8 100644 --- a/internal/store/mock/scheduled_message_event_store.go +++ b/internal/store/mock/scheduled_message_event_store.go @@ -11,7 +11,7 @@ import ( ) type ScheduledMessageEventKey struct { - RecipientId uuid.UUID + ContactId uuid.UUID MessageId uuid.UUID ScheduledMessageId uuid.UUID } @@ -94,7 +94,7 @@ func (m *MockScheduledMessageEventStore) Delete(ctx context.Context, id uuid.UUI copiedEventsKey := make(map[ScheduledMessageEventKey]*scheduling.ScheduledMessageEvent) for i, schMsgEvent := range m.ScheduledMessageEvents { - key := ScheduledMessageEventKey{RecipientId: schMsgEvent.RecipientId, MessageId: schMsgEvent.MessageId, ScheduledMessageId: schMsgEvent.ScheduledMessageId} + key := ScheduledMessageEventKey{ContactId: schMsgEvent.ContactId, MessageId: schMsgEvent.MessageId, ScheduledMessageId: schMsgEvent.ScheduledMessageId} if schMsgEvent.Id != id { copiedEvents[i] = schMsgEvent copiedEventsKey[key] = schMsgEvent @@ -132,7 +132,7 @@ func (m *MockScheduledMessageEventStore) CreateScheduledMessageEvent(ctx context event.Id = uuid.New() } - key := ScheduledMessageEventKey{RecipientId: event.RecipientId, MessageId: event.MessageId, ScheduledMessageId: event.ScheduledMessageId} + key := ScheduledMessageEventKey{ContactId: event.ContactId, MessageId: event.MessageId, ScheduledMessageId: event.ScheduledMessageId} if _, exists := m.ScheduledMessageEventsByKey[key]; exists { return fmt.Errorf("Already exists") @@ -152,7 +152,7 @@ func (m *MockScheduledMessageEventStore) Exists(ctx context.Context, event *sche return false, m.Error } - key := ScheduledMessageEventKey{RecipientId: event.RecipientId, MessageId: event.MessageId, ScheduledMessageId: event.ScheduledMessageId} + key := ScheduledMessageEventKey{ContactId: event.ContactId, MessageId: event.MessageId, ScheduledMessageId: event.ScheduledMessageId} _, exists := m.ScheduledMessageEventsByKey[key] return exists, nil diff --git a/internal/store/mock/store.go b/internal/store/mock/store.go index aa2b014..df469e8 100644 --- a/internal/store/mock/store.go +++ b/internal/store/mock/store.go @@ -36,16 +36,18 @@ func (m *MockMessageStore) CreateMessage(ctx context.Context, msg *message.Messa return m.Error } - if msg.Id == uuid.Nil { - msg.Id = uuid.New() + var id uuid.UUID + if msg.Id != nil && msg.Id == uuid.Nil { + id = uuid.New() + msg.Id = &id } - key := MessageKey{Content: msg.Content, UserId: msg.UserId} + key := MessageKey{Content: msg.Content, UserId: *msg.UserId} if _, exists := m.MessagesByKey[key]; exists { return errors.New("Message already exists") } - m.Messages[msg.Id] = msg + m.Messages[*msg.Id] = msg m.MessagesByKey[key] = msg return nil } @@ -88,7 +90,7 @@ func (m *MockMessageStore) MessageExists(ctx context.Context, msg *message.Messa return false, m.Error } - _, exists := m.MessagesByKey[MessageKey{Content: msg.Content, UserId: msg.UserId}] + _, exists := m.MessagesByKey[MessageKey{Content: msg.Content, UserId: *msg.UserId}] return exists, nil }