Skip to content

Commit

Permalink
add sns list subcriptions support
Browse files Browse the repository at this point in the history
add bad request ut case to listsubscriptionsv1

rename listSubscriptions test case

review ref
  • Loading branch information
NRatSony authored and Dai.Otsuka committed Aug 16, 2024
1 parent 2ca8cc6 commit f7595ad
Show file tree
Hide file tree
Showing 10 changed files with 393 additions and 106 deletions.
20 changes: 0 additions & 20 deletions app/gosns/gosns.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,26 +146,6 @@ func ConfirmSubscription(w http.ResponseWriter, req *http.Request) {

}

func ListSubscriptions(w http.ResponseWriter, req *http.Request) {
content := req.FormValue("ContentType")

uuid, _ := common.NewUUID()
respStruct := app.ListSubscriptionsResponse{}
respStruct.Xmlns = "http://queue.amazonaws.com/doc/2012-11-05/"
respStruct.Metadata.RequestId = uuid
respStruct.Result.Subscriptions.Member = make([]app.TopicMemberResult, 0, 0)

for _, topic := range app.SyncTopics.Topics {
for _, sub := range topic.Subscriptions {
tar := app.TopicMemberResult{TopicArn: topic.Arn, Protocol: sub.Protocol,
SubscriptionArn: sub.SubscriptionArn, Endpoint: sub.EndPoint, Owner: app.CurrentEnvironment.AccountID}
respStruct.Result.Subscriptions.Member = append(respStruct.Result.Subscriptions.Member, tar)
}
}

SendResponseBack(w, req, respStruct, content)
}

func ListSubscriptionsByTopic(w http.ResponseWriter, req *http.Request) {
content := req.FormValue("ContentType")
topicArn := req.FormValue("TopicArn")
Expand Down
59 changes: 0 additions & 59 deletions app/gosns/gosns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,65 +74,6 @@ func TestListSubscriptionByTopicResponse_No_Owner(t *testing.T) {
}
}

func TestListSubscriptionsResponse_No_Owner(t *testing.T) {
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "Local")
defer func() {
test.ResetApp()
}()

// set accountID to test value so it can be populated in response
app.CurrentEnvironment.AccountID = "100010001000"

// Create a request to pass to our handler. We don't have any query parameters for now, so we'll
// pass 'nil' as the third parameter.
req, err := http.NewRequest("POST", "/", nil)
if err != nil {
t.Fatal(err)
}

form := url.Values{}
form.Add("TopicArn", "arn:aws:sns:local:000000000000:local-topic1")
req.PostForm = form

// Prepare existant topic
topic := &app.Topic{
Name: "UnitTestTopic1",
Arn: "arn:aws:sns:local:100010001000:UnitTestTopic1",
Subscriptions: []*app.Subscription{
{
TopicArn: "",
Protocol: "",
SubscriptionArn: "",
EndPoint: "",
Raw: false,
FilterPolicy: &app.FilterPolicy{},
},
},
}
app.SyncTopics.Topics["UnitTestTopic1"] = topic

// We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
rr := httptest.NewRecorder()
handler := http.HandlerFunc(ListSubscriptions)

// Our handlers satisfy http.Handler, so we can call their ServeHTTP method
// directly and pass in our Request and ResponseRecorder.
handler.ServeHTTP(rr, req)

// Check the status code is what we expect.
if status := rr.Code; status != http.StatusOK {
t.Errorf("handler returned wrong status code: got %v want %v",
status, http.StatusOK)
}

// Check the response body is what we expect.
expected := `<Owner>` + app.CurrentEnvironment.AccountID + `</Owner>`
if !strings.Contains(rr.Body.String(), expected) {
t.Errorf("handler returned empty owner for subscription member: got %v want %v",
rr.Body.String(), expected)
}
}

func TestGetSubscriptionAttributesHandler_POST_Success(t *testing.T) {
// Create a request to pass to our handler. We don't have any query parameters for now, so we'll
// pass 'nil' as the third parameter.
Expand Down
40 changes: 40 additions & 0 deletions app/gosns/list_subscriptions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package gosns

import (
"net/http"

"github.com/google/uuid"

"github.com/Admiral-Piett/goaws/app"
"github.com/Admiral-Piett/goaws/app/models"
"github.com/Admiral-Piett/goaws/app/utils"

"github.com/Admiral-Piett/goaws/app/interfaces"
log "github.com/sirupsen/logrus"
)

func ListSubscriptionsV1(req *http.Request) (int, interfaces.AbstractResponseBody) {
requestBody := models.NewListSubscriptionsRequest()
ok := utils.REQUEST_TRANSFORMER(requestBody, req, false)
if !ok {
log.Error("Invalid Request - ListSubscriptionsV1")
return utils.CreateErrorResponseV1("InvalidParameterValue", false)
}

log.Debug("Listing Subscriptions")
requestId := uuid.NewString()
respStruct := models.ListSubscriptionsResponse{}
respStruct.Xmlns = models.BASE_XMLNS
respStruct.Metadata.RequestId = requestId
respStruct.Result.Subscriptions.Member = make([]models.TopicMemberResult, 0)

for _, topic := range app.SyncTopics.Topics {
for _, sub := range topic.Subscriptions {
tar := models.TopicMemberResult{TopicArn: topic.Arn, Protocol: sub.Protocol,
SubscriptionArn: sub.SubscriptionArn, Endpoint: sub.EndPoint, Owner: app.CurrentEnvironment.AccountID}
respStruct.Result.Subscriptions.Member = append(respStruct.Result.Subscriptions.Member, tar)
}
}

return http.StatusOK, respStruct
}
85 changes: 85 additions & 0 deletions app/gosns/list_subscriptions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package gosns

import (
"net/http"
"testing"

"github.com/Admiral-Piett/goaws/app/conf"
"github.com/Admiral-Piett/goaws/app/interfaces"
"github.com/Admiral-Piett/goaws/app/models"
"github.com/Admiral-Piett/goaws/app/test"
"github.com/Admiral-Piett/goaws/app/utils"
"github.com/stretchr/testify/assert"
)

func TestListSubcriptionsV1_NoSubscriptions(t *testing.T) {
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "NoQueuesOrTopics")
defer func() {
test.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.ListSubscriptionsRequest)
*v = models.ListSubscriptionsRequest{
NextToken: "",
}
return true
}

_, r := test.GenerateRequestInfo("POST", "/", nil, true)
code, res := ListSubscriptionsV1(r)

response, _ := res.(models.ListSubscriptionsResponse)

assert.Equal(t, http.StatusOK, code)
assert.Equal(t, models.BASE_XMLNS, response.Xmlns)
assert.NotEqual(t, "", response.Metadata)

assert.Len(t, response.Result.Subscriptions.Member, 0)
}

func TestListSubcriptionsV1_MultipleSubscriptions(t *testing.T) {
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "Local")
defer func() {
test.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
v := resultingStruct.(*models.ListSubscriptionsRequest)
*v = models.ListSubscriptionsRequest{
NextToken: "",
}
return true
}

_, r := test.GenerateRequestInfo("POST", "/", nil, true)
code, res := ListSubscriptionsV1(r)

response, _ := res.(models.ListSubscriptionsResponse)

assert.Equal(t, http.StatusOK, code)
assert.Equal(t, models.BASE_XMLNS, response.Xmlns)
assert.NotEqual(t, "", response.Metadata)

assert.Len(t, response.Result.Subscriptions.Member, 2)
assert.NotEqual(t, response.Result.Subscriptions.Member[0].SubscriptionArn, response.Result.Subscriptions.Member[1].SubscriptionArn)
}

func TestListSubscriptionsV1_request_transformer_error(t *testing.T) {
conf.LoadYamlConfig("../conf/mock-data/mock-config.yaml", "BaseUnitTests")
defer func() {
test.ResetApp()
utils.REQUEST_TRANSFORMER = utils.TransformRequest
}()

utils.REQUEST_TRANSFORMER = func(resultingStruct interfaces.AbstractRequestBody, req *http.Request, emptyRequestValid bool) (success bool) {
return false
}

_, r := test.GenerateRequestInfo("POST", "/", nil, true)
code, _ := ListSubscriptionsV1(r)

assert.Equal(t, http.StatusBadRequest, code)
}
32 changes: 32 additions & 0 deletions app/models/responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,3 +461,35 @@ func (r DeleteTopicResponse) GetResult() interface{} {
func (r DeleteTopicResponse) GetRequestId() string {
return r.Metadata.RequestId
}

/** List Subcriptions **/

type TopicMemberResult struct {
TopicArn string `xml:"TopicArn"`
Protocol string `xml:"Protocol"`
SubscriptionArn string `xml:"SubscriptionArn"`
Owner string `xml:"Owner"`
Endpoint string `xml:"Endpoint"`
}

type TopicSubscriptions struct {
Member []TopicMemberResult `xml:"member"`
}

type ListSubscriptionsResult struct {
Subscriptions TopicSubscriptions `xml:"Subscriptions"`
}

type ListSubscriptionsResponse struct {
Xmlns string `xml:"xmlns,attr"`
Result ListSubscriptionsResult `xml:"ListSubscriptionsResult"`
Metadata app.ResponseMetadata `xml:"ResponseMetadata"`
}

func (r ListSubscriptionsResponse) GetResult() interface{} {
return r.Result
}

func (r ListSubscriptionsResponse) GetRequestId() string {
return r.Metadata.RequestId
}
12 changes: 12 additions & 0 deletions app/models/sns.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,15 @@ type DeleteTopicRequest struct {
}

func (r *DeleteTopicRequest) SetAttributesFromForm(values url.Values) {}

// ListSubscriptionsV1

func NewListSubscriptionsRequest() *ListSubscriptionsRequest {
return &ListSubscriptionsRequest{}
}

type ListSubscriptionsRequest struct {
NextToken string `json:"NextToken" schema:"NextToken"` // not implemented
}

func (r *ListSubscriptionsRequest) SetAttributesFromForm(values url.Values) {}
14 changes: 7 additions & 7 deletions app/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,20 @@ var routingTableV1 = map[string]func(r *http.Request) (int, interfaces.AbstractR
"DeleteMessageBatch": sqs.DeleteMessageBatchV1,

// SNS
"Subscribe": sns.SubscribeV1,
"Unsubscribe": sns.UnsubscribeV1,
"Publish": sns.PublishV1,
"ListTopics": sns.ListTopicsV1,
"CreateTopic": sns.CreateTopicV1,
"DeleteTopic": sns.DeleteTopicV1,
"Subscribe": sns.SubscribeV1,
"Unsubscribe": sns.UnsubscribeV1,
"Publish": sns.PublishV1,
"ListTopics": sns.ListTopicsV1,
"CreateTopic": sns.CreateTopicV1,
"DeleteTopic": sns.DeleteTopicV1,
"ListSubscriptions": sns.ListSubscriptionsV1,
}

var routingTable = map[string]http.HandlerFunc{
// SNS
"SetSubscriptionAttributes": sns.SetSubscriptionAttributes,
"GetSubscriptionAttributes": sns.GetSubscriptionAttributes,
"ListSubscriptionsByTopic": sns.ListSubscriptionsByTopic,
"ListSubscriptions": sns.ListSubscriptions,

// SNS Internal
"ConfirmSubscription": sns.ConfirmSubscription,
Expand Down
14 changes: 7 additions & 7 deletions app/router/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,20 +271,20 @@ func TestActionHandler_v0_xml(t *testing.T) {
"DeleteMessageBatch": sqs.DeleteMessageBatchV1,

// SNS
"Subscribe": sns.SubscribeV1,
"Unsubscribe": sns.UnsubscribeV1,
"Publish": sns.PublishV1,
"ListTopics": sns.ListTopicsV1,
"CreateTopic": sns.CreateTopicV1,
"DeleteTopic": sns.DeleteTopicV1,
"Subscribe": sns.SubscribeV1,
"Unsubscribe": sns.UnsubscribeV1,
"Publish": sns.PublishV1,
"ListTopics": sns.ListTopicsV1,
"CreateTopic": sns.CreateTopicV1,
"DeleteTopic": sns.DeleteTopicV1,
"ListSubscriptions": sns.ListSubscriptionsV1,
}

routingTable = map[string]http.HandlerFunc{
// SNS
"SetSubscriptionAttributes": sns.SetSubscriptionAttributes,
"GetSubscriptionAttributes": sns.GetSubscriptionAttributes,
"ListSubscriptionsByTopic": sns.ListSubscriptionsByTopic,
"ListSubscriptions": sns.ListSubscriptions,

// SNS Internal
"ConfirmSubscription": sns.ConfirmSubscription,
Expand Down
15 changes: 2 additions & 13 deletions app/sns_messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ type GetSubscriptionAttributesResponse struct {
Metadata ResponseMetadata `xml:"ResponseMetadata,omitempty"`
}

/*** List Subscriptions Response */
/*** List Subscriptions By Topic Response */

type TopicMemberResult struct {
TopicArn string `xml:"TopicArn"`
Protocol string `xml:"Protocol"`
Expand All @@ -40,18 +41,6 @@ type TopicSubscriptions struct {
Member []TopicMemberResult `xml:"member"`
}

type ListSubscriptionsResult struct {
Subscriptions TopicSubscriptions `xml:"Subscriptions"`
}

type ListSubscriptionsResponse struct {
Xmlns string `xml:"xmlns,attr"`
Result ListSubscriptionsResult `xml:"ListSubscriptionsResult"`
Metadata ResponseMetadata `xml:"ResponseMetadata"`
}

/*** List Subscriptions By Topic Response */

type ListSubscriptionsByTopicResult struct {
Subscriptions TopicSubscriptions `xml:"Subscriptions"`
}
Expand Down
Loading

0 comments on commit f7595ad

Please sign in to comment.