From 15ec1a9ee41f2710e4f008a419ef7a617ca0b2db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Thu, 13 Aug 2026 22:06:26 +0400 Subject: [PATCH] =?UTF-8?q?chore:=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20=D1=83=D1=81=D1=82=D0=B0=D1=80=D0=B5=D0=B2=D1=88=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D1=8B=D0=B5=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20(SNS-=D0=BB=D0=B5=D0=B3=D0=B0?= =?UTF-8?q?=D1=81=D0=B8,=20=D0=BD=D0=B5=D1=81=D1=83=D1=89=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=B2=D1=83=D1=8E=D1=89=D0=B8=D0=B5=20=D0=B8=D0=BC=D0=BF?= =?UTF-8?q?=D0=BE=D1=80=D1=82=D1=8B)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/conf/config_test.go | 166 ----- app/gosqs/change_message_visibility_test.go | 75 -- app/models/conversions_test.go | 75 -- app/models/models_test.go | 73 -- app/models/requests_test.go | 739 -------------------- app/router/router_test.go | 251 ------- app/utils/utils_test.go | 139 ---- 7 files changed, 1518 deletions(-) delete mode 100644 app/conf/config_test.go delete mode 100644 app/gosqs/change_message_visibility_test.go delete mode 100644 app/models/conversions_test.go delete mode 100644 app/models/models_test.go delete mode 100644 app/models/requests_test.go delete mode 100644 app/router/router_test.go delete mode 100644 app/utils/utils_test.go diff --git a/app/conf/config_test.go b/app/conf/config_test.go deleted file mode 100644 index f7d8053..0000000 --- a/app/conf/config_test.go +++ /dev/null @@ -1,166 +0,0 @@ -package conf - -import ( - "testing" - - "shared-sqs/app/models" - - "github.com/stretchr/testify/assert" -) - -func TestConfig_NoQueuesOrTopics(t *testing.T) { - env := "NoQueuesOrTopics" - port := LoadYamlConfig("./mock-data/mock-config.yaml", env) - if port[0] != "4100" { - t.Errorf("Expected port number 4200 but got %s\n", port) - } - - numQueues := len(envs[env].Queues) - if numQueues != 0 { - t.Errorf("Expected zero queues to be in the environment but got %d\n", numQueues) - } - numQueues = len(models.SyncQueues.Queues) - if numQueues != 0 { - t.Errorf("Expected zero queues to be in the sqs topics but got %d\n", numQueues) - } - - numTopics := len(envs[env].Topics) - if numTopics != 0 { - t.Errorf("Expected zero topics to be in the environment but got %d\n", numTopics) - } - numTopics = len(models.SyncTopics.Topics) - if numTopics != 0 { - t.Errorf("Expected zero topics to be in the sns topics but got %d\n", numTopics) - } -} - -func TestConfig_CreateQueuesTopicsAndSubscriptions(t *testing.T) { - env := "Local" - port := LoadYamlConfig("./mock-data/mock-config.yaml", env) - if port[0] != "4100" { - t.Errorf("Expected port number 4100 but got %s\n", port) - } - - numQueues := len(envs[env].Queues) - if numQueues != 4 { - t.Errorf("Expected three queues to be in the environment but got %d\n", numQueues) - } - numQueues = len(models.SyncQueues.Queues) - if numQueues != 6 { - t.Errorf("Expected five queues to be in the sqs topics but got %d\n", numQueues) - } - - numTopics := len(envs[env].Topics) - if numTopics != 2 { - t.Errorf("Expected two topics to be in the environment but got %d\n", numTopics) - } - numTopics = len(models.SyncTopics.Topics) - if numTopics != 2 { - t.Errorf("Expected two topics to be in the sns topics but got %d\n", numTopics) - } -} - -func TestConfig_QueueAttributes(t *testing.T) { - var emptyQueue *models.Queue - env := "Local" - port := LoadYamlConfig("./mock-data/mock-config.yaml", env) - if port[0] != "4100" { - t.Errorf("Expected port number 4100 but got %s\n", port) - } - - assert.Equal(t, 10, models.SyncQueues.Queues["local-queue1"].ReceiveMessageWaitTimeSeconds) - assert.Equal(t, 10, models.SyncQueues.Queues["local-queue1"].VisibilityTimeout) - assert.Equal(t, 1024, models.SyncQueues.Queues["local-queue1"].MaximumMessageSize) - assert.Equal(t, emptyQueue, models.SyncQueues.Queues["local-queue1"].DeadLetterQueue) - assert.Equal(t, 0, models.SyncQueues.Queues["local-queue1"].MaxReceiveCount) - assert.Equal(t, 345600, models.SyncQueues.Queues["local-queue1"].MessageRetentionPeriod) - assert.Equal(t, 100, models.SyncQueues.Queues["local-queue3"].MaxReceiveCount) - - assert.Equal(t, "local-queue3-dlq", models.SyncQueues.Queues["local-queue3"].DeadLetterQueue.Name) - assert.Equal(t, 128, models.SyncQueues.Queues["local-queue2"].MaximumMessageSize) - assert.Equal(t, 150, models.SyncQueues.Queues["local-queue2"].VisibilityTimeout) - assert.Equal(t, 245600, models.SyncQueues.Queues["local-queue2"].MessageRetentionPeriod) -} - -func TestConfig_NoQueueAttributeDefaults(t *testing.T) { - env := "NoQueueAttributeDefaults" - LoadYamlConfig("./mock-data/mock-config.yaml", env) - - receiveWaitTime := models.SyncQueues.Queues["local-queue1"].ReceiveMessageWaitTimeSeconds - if receiveWaitTime != 0 { - t.Errorf("Expected local-queue1 Queue to be configured with ReceiveMessageWaitTimeSeconds: 0 but got %d\n", receiveWaitTime) - } - timeoutSecs := models.SyncQueues.Queues["local-queue1"].VisibilityTimeout - if timeoutSecs != 30 { - t.Errorf("Expected local-queue1 Queue to be configured with VisibilityTimeout: 30 but got %d\n", timeoutSecs) - } - - receiveWaitTime = models.SyncQueues.Queues["local-queue2"].ReceiveMessageWaitTimeSeconds - if receiveWaitTime != 20 { - t.Errorf("Expected local-queue2 Queue to be configured with ReceiveMessageWaitTimeSeconds: 20 but got %d\n", receiveWaitTime) - } - - messageRetentionPeriod := models.SyncQueues.Queues["local-queue1"].MessageRetentionPeriod - if messageRetentionPeriod != 345600 { - t.Errorf("Expected local-queue2 Queue to be configured with VisibilityTimeout: 150 but got %d\n", timeoutSecs) - } -} - -func TestConfig_invalid_config_resorts_to_default_queue_attributes(t *testing.T) { - env := "missing" - port := LoadYamlConfig("./mock-data/mock-config.yaml", env) - if port[0] != "4100" { - t.Errorf("Expected port number 4100 but got %s\n", port) - } - - assert.Equal(t, 262144, models.CurrentEnvironment.QueueAttributeDefaults.MaximumMessageSize) - assert.Equal(t, 345600, models.CurrentEnvironment.QueueAttributeDefaults.MessageRetentionPeriod) - assert.Equal(t, 0, models.CurrentEnvironment.QueueAttributeDefaults.ReceiveMessageWaitTimeSeconds) - assert.Equal(t, 30, models.CurrentEnvironment.QueueAttributeDefaults.VisibilityTimeout) -} - -func TestConfig_LoadYamlConfig_finds_default_config(t *testing.T) { - expectedQueues := []string{ - "local-queue1", - "local-queue2", - "local-queue3", - "local-queue3-dlq", - "local-queue4", - } - expectedTopics := []string{ - "local-topic1", - "local-topic2", - "local-topic3", - "local-topic4", - } - - env := "Local" - LoadYamlConfig("", env) - - queues := models.SyncQueues.Queues - topics := models.SyncTopics.Topics - for _, expectedName := range expectedQueues { - _, ok := queues[expectedName] - assert.True(t, ok) - } - for _, expectedName := range expectedTopics { - _, ok := topics[expectedName] - assert.True(t, ok) - } -} - -func TestConfig_LoadYamlConfig_missing_config_loads_nothing(t *testing.T) { - models.CurrentEnvironment = models.Environment{} - ports := LoadYamlConfig("/garbage", "Local") - - assert.Equal(t, []string{"4100"}, ports) - assert.Equal(t, models.CurrentEnvironment, models.Environment{}) -} - -func TestConfig_LoadYamlConfig_invalid_config_loads_nothing(t *testing.T) { - models.CurrentEnvironment = models.Environment{} - ports := LoadYamlConfig("../common/common.go", "Local") - - assert.Equal(t, []string{"4100"}, ports) - assert.Equal(t, models.CurrentEnvironment, models.Environment{}) -} diff --git a/app/gosqs/change_message_visibility_test.go b/app/gosqs/change_message_visibility_test.go deleted file mode 100644 index 2e9adac..0000000 --- a/app/gosqs/change_message_visibility_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package gosqs - -import ( - "net/http" - "testing" - - "shared-sqs/app/test" - - "shared-sqs/app/fixtures" - "shared-sqs/app/models" - "github.com/stretchr/testify/assert" -) - -func TestChangeMessageVisibility_success(t *testing.T) { - // create a queue - models.CurrentEnvironment = fixtures.LOCAL_ENVIRONMENT - defer func() { - models.ResetApp() - }() - - q := &models.Queue{ - Name: "testing", - Messages: []models.SqsMessage{{ - MessageBody: "test1", - ReceiptHandle: "123", - }}, - } - models.SyncQueues.Queues["testing"] = q - - // The default value for the VisibilityTimeout is the zero value of time.Time - assert.Zero(t, q.Messages[0].VisibilityTimeout) - - _, r := test.GenerateRequestInfo("POST", "/", models.ChangeMessageVisibilityRequest{ - QueueUrl: "http://localhost:4100/queue/testing", - ReceiptHandle: "123", - VisibilityTimeout: 0, - }, true) - status, _ := ChangeMessageVisibilityV1(r) - assert.Equal(t, status, http.StatusOK) - - // Changing the message visibility increments the time.Time by N seconds - // from the current time. - // - // Given that the current time is relative between calling the endpoint and - // the time being set, we can't reliably assert an exact value. So assert - // that the time.Time value is no longer the default zero value. - assert.NotZero(t, q.Messages[0].VisibilityTimeout) - assert.NotZero(t, q.Messages[0].ReceiptTime) - assert.Equal(t, "", q.Messages[0].ReceiptHandle) - assert.Equal(t, 1, q.Messages[0].Retry) -} - -func TestChangeMessageVisibility_success_adds_to_existing_visibility_timeout(t *testing.T) { - // TODO -} - -func TestChangeMessageVisibility_success_transfers_to_dead_letter_queue(t *testing.T) { - // TODO -} - -func TestChangeMessageVisibility_request_transformer_error(t *testing.T) { - // TODO -} - -func TestChangeMessageVisibility_visibility_timeout_too_large(t *testing.T) { - // TODO -} - -func TestChangeMessageVisibility_missing_queue(t *testing.T) { - // TODO -} - -func TestChangeMessageVisibility_missing_message(t *testing.T) { - // TODO - mismatch receipt handle -} diff --git a/app/models/conversions_test.go b/app/models/conversions_test.go deleted file mode 100644 index 3814dbd..0000000 --- a/app/models/conversions_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package models - -import ( - "encoding/json" - "testing" - - "shared-sqs/app/test" - "github.com/stretchr/testify/assert" -) - -type StringToIntStruct struct { - Field1 StringToInt `json:"Field1"` - Field2 StringToInt `json:"Field2"` -} - -func TestStringToInt_unmarshalJSON_int(t *testing.T) { - body := struct { - Field1 int `json:"Field1"` - Field2 int `json:"Field2"` - }{ - Field1: 1, - Field2: 2, - } - _, r := test.GenerateRequestInfo("POST", "/", body, true) - - result := &StringToIntStruct{} - decoder := json.NewDecoder(r.Body) - err := decoder.Decode(result) - - assert.Nil(t, err) - assert.Equal(t, StringToInt(1), result.Field1) - assert.Equal(t, StringToInt(2), result.Field2) -} - -func TestStringToInt_unmarshalJSON_string(t *testing.T) { - body := struct { - Field1 string `json:"Field1"` - Field2 string `json:"Field2"` - }{ - Field1: "1", - Field2: "2", - } - _, r := test.GenerateRequestInfo("POST", "/", body, true) - - result := &StringToIntStruct{} - decoder := json.NewDecoder(r.Body) - err := decoder.Decode(result) - - assert.Nil(t, err) - assert.Equal(t, StringToInt(1), result.Field1) - assert.Equal(t, StringToInt(2), result.Field2) -} - -func TestStringToInt_unmarshalJSON_invalid_type_returns_error(t *testing.T) { - body := struct { - Field1 bool `json:"Field1"` - Field2 bool `json:"Field2"` - }{ - Field1: true, - Field2: false, - } - _, r := test.GenerateRequestInfo("POST", "/", body, true) - - result := &StringToIntStruct{} - decoder := json.NewDecoder(r.Body) - err := decoder.Decode(result) - - assert.Error(t, err) -} - -func TestStringToInt_int_returns_int_type(t *testing.T) { - s := StringToInt(1) - - assert.Equal(t, int(1), s.Int()) -} diff --git a/app/models/models_test.go b/app/models/models_test.go deleted file mode 100644 index 4954b07..0000000 --- a/app/models/models_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package models - -import ( - "testing" - "time" - - "github.com/stretchr/testify/assert" -) - -func TestFilterPolicy_IsSatisfiedBy(t *testing.T) { - var tests = []struct { - filterPolicy *FilterPolicy - messageAttributes map[string]MessageAttribute - expected bool - }{ - { - &FilterPolicy{"foo": {"bar"}}, - map[string]MessageAttribute{"foo": {DataType: "String", StringValue: "bar"}}, - true, - }, - { - &FilterPolicy{"foo": {"bar", "xyz"}}, - map[string]MessageAttribute{"foo": {DataType: "String", StringValue: "xyz"}}, - true, - }, - { - &FilterPolicy{"foo": {"bar", "xyz"}, "abc": {"def"}}, - map[string]MessageAttribute{"foo": {DataType: "String", StringValue: "xyz"}, - "abc": {DataType: "String", StringValue: "def"}}, - true, - }, - { - &FilterPolicy{"foo": {"bar"}}, - map[string]MessageAttribute{"foo": {DataType: "String", StringValue: "baz"}}, - false, - }, - { - &FilterPolicy{"foo": {"bar"}}, - map[string]MessageAttribute{}, - false, - }, - { - &FilterPolicy{"foo": {"bar"}, "abc": {"def"}}, - map[string]MessageAttribute{"foo": {DataType: "String", StringValue: "bar"}}, - false, - }, - { - &FilterPolicy{"foo": {"bar"}}, - map[string]MessageAttribute{"foo": {DataType: "Binary", BinaryValue: "bar"}}, - false, - }, - } - - for i, tt := range tests { - actual := tt.filterPolicy.IsSatisfiedBy(tt.messageAttributes) - if tt.filterPolicy.IsSatisfiedBy(tt.messageAttributes) != tt.expected { - t.Errorf("#%d FilterPolicy: expected %t, actual %t", i, tt.expected, actual) - } - } - -} - -func TestMessage_IsReadyForReceipt(t *testing.T) { - CurrentEnvironment.RandomLatency.Min = 100 - CurrentEnvironment.RandomLatency.Max = 100 - msg := SqsMessage{ - SentTime: time.Now(), - } - assert.False(t, msg.IsReadyForReceipt()) - duration, _ := time.ParseDuration("105ms") - time.Sleep(duration) - assert.True(t, msg.IsReadyForReceipt()) -} diff --git a/app/models/requests_test.go b/app/models/requests_test.go deleted file mode 100644 index 9da5849..0000000 --- a/app/models/requests_test.go +++ /dev/null @@ -1,739 +0,0 @@ -package models - -import ( - "encoding/json" - "fmt" - "math/rand" - "net/url" - "sync" - "testing" - "time" - - "github.com/stretchr/testify/assert" -) - -func TestNewCreateQueueRequest(t *testing.T) { - CurrentEnvironment.QueueAttributeDefaults.MaximumMessageSize = 262144 - CurrentEnvironment.QueueAttributeDefaults.MessageRetentionPeriod = 345600 - CurrentEnvironment.QueueAttributeDefaults.ReceiveMessageWaitTimeSeconds = 10 - CurrentEnvironment.QueueAttributeDefaults.VisibilityTimeout = 30 - defer func() { - ResetApp() - }() - - expectedCreateQueueRequest := &CreateQueueRequest{ - Attributes: QueueAttributes{ - DelaySeconds: 0, - MaximumMessageSize: 262144, - MessageRetentionPeriod: 345600, - ReceiveMessageWaitTimeSeconds: 10, - VisibilityTimeout: 30, - }, - } - - result := NewCreateQueueRequest() - - assert.Equal(t, expectedCreateQueueRequest, result) -} - -func TestCreateQueueRequest_SetAttributesFromForm_success(t *testing.T) { - expectedRedrivePolicy := RedrivePolicy{ - MaxReceiveCount: 100, - DeadLetterTargetArn: "dead-letter-queue-arn", - } - - form := url.Values{} - form.Add("Action", "CreateQueue") - form.Add("QueueName", "new-queue") - form.Add("Version", "2012-11-05") - form.Add("Attribute.1.Name", "DelaySeconds") - form.Add("Attribute.1.Value", "1") - form.Add("Attribute.2.Name", "MaximumMessageSize") - form.Add("Attribute.2.Value", "2") - form.Add("Attribute.3.Name", "MessageRetentionPeriod") - form.Add("Attribute.3.Value", "3") - form.Add("Attribute.4.Name", "Policy") - form.Add("Attribute.4.Value", "{\"i-am\":\"the-policy\"}") - form.Add("Attribute.5.Name", "ReceiveMessageWaitTimeSeconds") - form.Add("Attribute.5.Value", "4") - form.Add("Attribute.6.Name", "VisibilityTimeout") - form.Add("Attribute.6.Value", "5") - form.Add("Attribute.7.Name", "RedrivePolicy") - form.Add("Attribute.7.Value", "{\"maxReceiveCount\": 100, \"deadLetterTargetArn\":\"dead-letter-queue-arn\"}") - form.Add("Attribute.8.Name", "RedriveAllowPolicy") - form.Add("Attribute.8.Value", "{\"i-am\":\"the-redrive-allow-policy\"}") - - cqr := &CreateQueueRequest{ - Attributes: QueueAttributes{ - DelaySeconds: 1, - MaximumMessageSize: 262144, - MessageRetentionPeriod: 345600, - ReceiveMessageWaitTimeSeconds: 10, - VisibilityTimeout: 30, - }, - } - cqr.SetAttributesFromForm(form) - - assert.Equal(t, StringToInt(1), cqr.Attributes.DelaySeconds) - assert.Equal(t, StringToInt(2), cqr.Attributes.MaximumMessageSize) - assert.Equal(t, StringToInt(3), cqr.Attributes.MessageRetentionPeriod) - assert.Equal(t, map[string]interface{}{"i-am": "the-policy"}, cqr.Attributes.Policy) - assert.Equal(t, StringToInt(4), cqr.Attributes.ReceiveMessageWaitTimeSeconds) - assert.Equal(t, StringToInt(5), cqr.Attributes.VisibilityTimeout) - assert.Equal(t, expectedRedrivePolicy, cqr.Attributes.RedrivePolicy) - assert.Equal(t, map[string]interface{}{"i-am": "the-redrive-allow-policy"}, cqr.Attributes.RedriveAllowPolicy) -} - -func TestCreateQueueRequest_SetAttributesFromForm_success_handles_redrive_recieve_count_int(t *testing.T) { - expectedRedrivePolicy := RedrivePolicy{ - MaxReceiveCount: 100, - DeadLetterTargetArn: "dead-letter-queue-arn", - } - - form := url.Values{} - form.Add("Attribute.1.Name", "RedrivePolicy") - form.Add("Attribute.1.Value", "{\"maxReceiveCount\": 100, \"deadLetterTargetArn\":\"dead-letter-queue-arn\"}") - - cqr := &CreateQueueRequest{ - Attributes: QueueAttributes{}, - } - cqr.SetAttributesFromForm(form) - - assert.Equal(t, expectedRedrivePolicy, cqr.Attributes.RedrivePolicy) -} - -func TestCreateQueueRequest_SetAttributesFromForm_success_handles_redrive_recieve_count_string(t *testing.T) { - expectedRedrivePolicy := RedrivePolicy{ - MaxReceiveCount: 100, - DeadLetterTargetArn: "dead-letter-queue-arn", - } - - form := url.Values{} - form.Add("Attribute.1.Name", "RedrivePolicy") - form.Add("Attribute.1.Value", "{\"maxReceiveCount\": \"100\", \"deadLetterTargetArn\":\"dead-letter-queue-arn\"}") - - cqr := &CreateQueueRequest{ - Attributes: QueueAttributes{}, - } - cqr.SetAttributesFromForm(form) - - assert.Equal(t, expectedRedrivePolicy, cqr.Attributes.RedrivePolicy) -} - -func TestCreateQueueRequest_SetAttributesFromForm_success_default_unparsable_redrive_recieve_count(t *testing.T) { - defaultRedrivePolicy := RedrivePolicy{ - MaxReceiveCount: 10, - DeadLetterTargetArn: "dead-letter-queue-arn", - } - - form := url.Values{} - form.Add("Attribute.1.Name", "RedrivePolicy") - form.Add("Attribute.1.Value", "{\"maxReceiveCount\": null, \"deadLetterTargetArn\":\"dead-letter-queue-arn\"}") - - cqr := &CreateQueueRequest{ - Attributes: QueueAttributes{}, - } - cqr.SetAttributesFromForm(form) - - assert.Equal(t, defaultRedrivePolicy, cqr.Attributes.RedrivePolicy) -} - -func TestCreateQueueRequest_SetAttributesFromForm_success_skips_invalid_values(t *testing.T) { - form := url.Values{} - form.Add("Attribute.1.Name", "DelaySeconds") - form.Add("Attribute.1.Value", "garbage") - form.Add("Attribute.2.Name", "MaximumMessageSize") - form.Add("Attribute.2.Value", "garbage") - form.Add("Attribute.3.Name", "MessageRetentionPeriod") - form.Add("Attribute.3.Value", "garbage") - form.Add("Attribute.4.Name", "Policy") - form.Add("Attribute.4.Value", "garbage") - form.Add("Attribute.5.Name", "ReceiveMessageWaitTimeSeconds") - form.Add("Attribute.5.Value", "garbage") - form.Add("Attribute.6.Name", "VisibilityTimeout") - form.Add("Attribute.6.Value", "garbage") - form.Add("Attribute.7.Name", "RedrivePolicy") - form.Add("Attribute.7.Value", "garbage") - form.Add("Attribute.8.Name", "RedriveAllowPolicy") - form.Add("Attribute.8.Value", "garbage") - - cqr := &CreateQueueRequest{ - Attributes: QueueAttributes{ - DelaySeconds: 1, - MaximumMessageSize: 262144, - MessageRetentionPeriod: 345600, - ReceiveMessageWaitTimeSeconds: 10, - VisibilityTimeout: 30, - }, - } - cqr.SetAttributesFromForm(form) - - assert.Equal(t, StringToInt(1), cqr.Attributes.DelaySeconds) - assert.Equal(t, StringToInt(262144), cqr.Attributes.MaximumMessageSize) - assert.Equal(t, StringToInt(345600), cqr.Attributes.MessageRetentionPeriod) - assert.Equal(t, map[string]interface{}(nil), cqr.Attributes.Policy) - assert.Equal(t, StringToInt(10), cqr.Attributes.ReceiveMessageWaitTimeSeconds) - assert.Equal(t, StringToInt(30), cqr.Attributes.VisibilityTimeout) - assert.Equal(t, RedrivePolicy{}, cqr.Attributes.RedrivePolicy) - assert.Equal(t, map[string]interface{}(nil), cqr.Attributes.RedriveAllowPolicy) -} - -func TestRedrivePolicy_UnmarshalJSON_handles_nested_json(t *testing.T) { - request := struct { - MaxReceiveCount int `json:"maxReceiveCount"` - DeadLetterTargetArn string `json:"deadLetterTargetArn"` - }{ - MaxReceiveCount: 100, - DeadLetterTargetArn: "arn:redrive-queue", - } - b, _ := json.Marshal(request) - var r = RedrivePolicy{} - err := r.UnmarshalJSON(b) - - assert.Nil(t, err) - assert.Equal(t, StringToInt(100), r.MaxReceiveCount) - assert.Equal(t, fmt.Sprintf("%s:%s", "arn", "redrive-queue"), r.DeadLetterTargetArn) -} - -func TestRedrivePolicy_UnmarshalJSON_handles_escaped_string(t *testing.T) { - request := `{"maxReceiveCount":"100","deadLetterTargetArn":"arn:redrive-queue"}` - b, _ := json.Marshal(request) - var r = RedrivePolicy{} - err := r.UnmarshalJSON(b) - - assert.Nil(t, err) - assert.Equal(t, StringToInt(100), r.MaxReceiveCount) - assert.Equal(t, fmt.Sprintf("%s:%s", "arn", "redrive-queue"), r.DeadLetterTargetArn) -} - -func TestRedrivePolicy_UnmarshalJSON_invalid_json_request_returns_error(t *testing.T) { - request := fmt.Sprintf(`{\"maxReceiveCount\":\"100\",\"deadLetterTargetArn\":\"arn:redrive-queue\"}`) - var r = RedrivePolicy{} - err := r.UnmarshalJSON([]byte(request)) - - assert.Error(t, err) - assert.Equal(t, StringToInt(0), r.MaxReceiveCount) - assert.Equal(t, "", r.DeadLetterTargetArn) -} - -func TestRedrivePolicy_UnmarshalJSON_invalid_type_returns_error(t *testing.T) { - request := `{"maxReceiveCount":true,"deadLetterTargetArn":"arn:redrive-queue"}` - b, _ := json.Marshal(request) - var r = RedrivePolicy{} - err := r.UnmarshalJSON(b) - - assert.Error(t, err) - assert.Equal(t, StringToInt(0), r.MaxReceiveCount) - assert.Equal(t, "", r.DeadLetterTargetArn) -} - -func TestNewListQueuesRequest_SetAttributesFromForm(t *testing.T) { - form := url.Values{} - form.Add("MaxResults", "1") - form.Add("NextToken", "next-token") - form.Add("QueueNamePrefix", "queue-name-prefix") - - lqr := &ListQueueRequest{} - lqr.SetAttributesFromForm(form) - - assert.Equal(t, 1, lqr.MaxResults) - assert.Equal(t, "next-token", lqr.NextToken) - assert.Equal(t, "queue-name-prefix", lqr.QueueNamePrefix) -} - -func TestListQueuesRequest_SetAttributesFromForm_invalid_max_results(t *testing.T) { - form := url.Values{} - form.Add("MaxResults", "1.0") - form.Add("NextToken", "next-token") - form.Add("QueueNamePrefix", "queue-name-prefix") - - lqr := &ListQueueRequest{} - lqr.SetAttributesFromForm(form) - - assert.Equal(t, 0, lqr.MaxResults) - assert.Equal(t, "next-token", lqr.NextToken) - assert.Equal(t, "queue-name-prefix", lqr.QueueNamePrefix) -} - -func TestGetQueueAttributesRequest_SetAttributesFromForm(t *testing.T) { - form := url.Values{} - form.Add("QueueUrl", "queue-url") - form.Add("AttributeName.1", "attribute-1") - form.Add("AttributeName.2", "attribute-2") - - lqr := &GetQueueAttributesRequest{} - lqr.SetAttributesFromForm(form) - - assert.Equal(t, "queue-url", lqr.QueueUrl) - assert.Equal(t, 2, len(lqr.AttributeNames)) - assert.Contains(t, lqr.AttributeNames, "attribute-1") - assert.Contains(t, lqr.AttributeNames, "attribute-2") -} - -func TestGetQueueAttributesRequest_SetAttributesFromForm_skips_invalid_key_sequence(t *testing.T) { - form := url.Values{} - form.Add("QueueUrl", "queue-url") - form.Add("AttributeName.1", "attribute-1") - form.Add("AttributeName.3", "attribute-3") - - lqr := &GetQueueAttributesRequest{} - lqr.SetAttributesFromForm(form) - - assert.Equal(t, "queue-url", lqr.QueueUrl) - assert.Equal(t, 1, len(lqr.AttributeNames)) - assert.Contains(t, lqr.AttributeNames, "attribute-1") -} - -func TestSendMessageRequest_SetAttributesFromForm_success(t *testing.T) { - form := url.Values{} - form.Add("MessageAttribute.1.Name", "Attr1") - form.Add("MessageAttribute.1.Value.DataType", "String") - form.Add("MessageAttribute.1.Value.StringValue", "Value1") - form.Add("MessageAttribute.2.Name", "Attr2") - form.Add("MessageAttribute.2.Value.DataType", "Binary") - form.Add("MessageAttribute.2.Value.BinaryValue", "VmFsdWUy") - form.Add("MessageAttribute.3.Name", "") - form.Add("MessageAttribute.3.Value.DataType", "String") - form.Add("MessageAttribute.3.Value.StringValue", "Value") - form.Add("MessageAttribute.4.Name", "Attr4") - form.Add("MessageAttribute.4.Value.DataType", "") - form.Add("MessageAttribute.4.Value.StringValue", "Value4") - - r := &SendMessageRequest{ - MessageAttributes: make(map[string]MessageAttribute), - MessageSystemAttributes: make(map[string]MessageAttribute), - } - r.SetAttributesFromForm(form) - - assert.Equal(t, 2, len(r.MessageAttributes)) - - assert.NotNil(t, r.MessageAttributes["Attr1"]) - attr1 := r.MessageAttributes["Attr1"] - assert.Equal(t, "String", attr1.DataType) - assert.Equal(t, "Value1", attr1.StringValue) - assert.Empty(t, attr1.BinaryValue) - - assert.NotNil(t, r.MessageAttributes["Attr2"]) - attr2 := r.MessageAttributes["Attr2"] - assert.Equal(t, "Binary", attr2.DataType) - assert.Empty(t, attr2.StringValue) - assert.Equal(t, "VmFsdWUy", attr2.BinaryValue) -} - -func TestSetQueueAttributesRequest_SetAttributesFromForm_success(t *testing.T) { - expectedRedrivePolicy := RedrivePolicy{ - MaxReceiveCount: 100, - DeadLetterTargetArn: "dead-letter-queue-arn", - } - - form := url.Values{} - form.Add("Action", "CreateQueue") - form.Add("QueueName", "new-queue") - form.Add("Version", "2012-11-05") - form.Add("Attribute.1.Name", "DelaySeconds") - form.Add("Attribute.1.Value", "1") - form.Add("Attribute.2.Name", "MaximumMessageSize") - form.Add("Attribute.2.Value", "2") - form.Add("Attribute.3.Name", "MessageRetentionPeriod") - form.Add("Attribute.3.Value", "3") - form.Add("Attribute.4.Name", "Policy") - form.Add("Attribute.4.Value", "{\"i-am\":\"the-policy\"}") - form.Add("Attribute.5.Name", "ReceiveMessageWaitTimeSeconds") - form.Add("Attribute.5.Value", "4") - form.Add("Attribute.6.Name", "VisibilityTimeout") - form.Add("Attribute.6.Value", "5") - form.Add("Attribute.7.Name", "RedrivePolicy") - form.Add("Attribute.7.Value", "{\"maxReceiveCount\": 100, \"deadLetterTargetArn\":\"dead-letter-queue-arn\"}") - form.Add("Attribute.8.Name", "RedriveAllowPolicy") - form.Add("Attribute.8.Value", "{\"i-am\":\"the-redrive-allow-policy\"}") - - cqr := &SetQueueAttributesRequest{ - Attributes: QueueAttributes{ - DelaySeconds: 1, - MaximumMessageSize: 262144, - MessageRetentionPeriod: 345600, - ReceiveMessageWaitTimeSeconds: 10, - VisibilityTimeout: 30, - }, - } - cqr.SetAttributesFromForm(form) - - assert.Equal(t, StringToInt(1), cqr.Attributes.DelaySeconds) - assert.Equal(t, StringToInt(2), cqr.Attributes.MaximumMessageSize) - assert.Equal(t, StringToInt(3), cqr.Attributes.MessageRetentionPeriod) - assert.Equal(t, map[string]interface{}{"i-am": "the-policy"}, cqr.Attributes.Policy) - assert.Equal(t, StringToInt(4), cqr.Attributes.ReceiveMessageWaitTimeSeconds) - assert.Equal(t, StringToInt(5), cqr.Attributes.VisibilityTimeout) - assert.Equal(t, expectedRedrivePolicy, cqr.Attributes.RedrivePolicy) - assert.Equal(t, map[string]interface{}{"i-am": "the-redrive-allow-policy"}, cqr.Attributes.RedriveAllowPolicy) -} - -func TestSetQueueAttributesRequest_SetAttributesFromForm_success_handles_redrive_recieve_count_int(t *testing.T) { - expectedRedrivePolicy := RedrivePolicy{ - MaxReceiveCount: 100, - DeadLetterTargetArn: "dead-letter-queue-arn", - } - - form := url.Values{} - form.Add("Attribute.1.Name", "RedrivePolicy") - form.Add("Attribute.1.Value", "{\"maxReceiveCount\": 100, \"deadLetterTargetArn\":\"dead-letter-queue-arn\"}") - - cqr := &SetQueueAttributesRequest{ - Attributes: QueueAttributes{}, - } - cqr.SetAttributesFromForm(form) - - assert.Equal(t, expectedRedrivePolicy, cqr.Attributes.RedrivePolicy) -} - -func TestSetQueueAttributesRequest_SetAttributesFromForm_success_handles_redrive_recieve_count_string(t *testing.T) { - expectedRedrivePolicy := RedrivePolicy{ - MaxReceiveCount: 100, - DeadLetterTargetArn: "dead-letter-queue-arn", - } - - form := url.Values{} - form.Add("Attribute.1.Name", "RedrivePolicy") - form.Add("Attribute.1.Value", "{\"maxReceiveCount\": \"100\", \"deadLetterTargetArn\":\"dead-letter-queue-arn\"}") - - cqr := &SetQueueAttributesRequest{ - Attributes: QueueAttributes{}, - } - cqr.SetAttributesFromForm(form) - - assert.Equal(t, expectedRedrivePolicy, cqr.Attributes.RedrivePolicy) -} - -func TestSetQueueAttributesRequest_SetAttributesFromForm_success_default_unparsable_redrive_recieve_count(t *testing.T) { - defaultRedrivePolicy := RedrivePolicy{ - MaxReceiveCount: 10, - DeadLetterTargetArn: "dead-letter-queue-arn", - } - - form := url.Values{} - form.Add("Attribute.1.Name", "RedrivePolicy") - form.Add("Attribute.1.Value", "{\"maxReceiveCount\": null, \"deadLetterTargetArn\":\"dead-letter-queue-arn\"}") - - cqr := &SetQueueAttributesRequest{ - Attributes: QueueAttributes{}, - } - cqr.SetAttributesFromForm(form) - - assert.Equal(t, defaultRedrivePolicy, cqr.Attributes.RedrivePolicy) -} - -func TestSetQueueAttributesRequest_SetAttributesFromForm_success_skips_invalid_values(t *testing.T) { - form := url.Values{} - form.Add("Attribute.1.Name", "DelaySeconds") - form.Add("Attribute.1.Value", "garbage") - form.Add("Attribute.2.Name", "MaximumMessageSize") - form.Add("Attribute.2.Value", "garbage") - form.Add("Attribute.3.Name", "MessageRetentionPeriod") - form.Add("Attribute.3.Value", "garbage") - form.Add("Attribute.4.Name", "Policy") - form.Add("Attribute.4.Value", "garbage") - form.Add("Attribute.5.Name", "ReceiveMessageWaitTimeSeconds") - form.Add("Attribute.5.Value", "garbage") - form.Add("Attribute.6.Name", "VisibilityTimeout") - form.Add("Attribute.6.Value", "garbage") - form.Add("Attribute.7.Name", "RedrivePolicy") - form.Add("Attribute.7.Value", "garbage") - form.Add("Attribute.8.Name", "RedriveAllowPolicy") - form.Add("Attribute.8.Value", "garbage") - - cqr := &SetQueueAttributesRequest{ - Attributes: QueueAttributes{ - DelaySeconds: 1, - MaximumMessageSize: 262144, - MessageRetentionPeriod: 345600, - ReceiveMessageWaitTimeSeconds: 10, - VisibilityTimeout: 30, - }, - } - cqr.SetAttributesFromForm(form) - - assert.Equal(t, StringToInt(1), cqr.Attributes.DelaySeconds) - assert.Equal(t, StringToInt(262144), cqr.Attributes.MaximumMessageSize) - assert.Equal(t, StringToInt(345600), cqr.Attributes.MessageRetentionPeriod) - assert.Equal(t, map[string]interface{}(nil), cqr.Attributes.Policy) - assert.Equal(t, StringToInt(10), cqr.Attributes.ReceiveMessageWaitTimeSeconds) - assert.Equal(t, StringToInt(30), cqr.Attributes.VisibilityTimeout) - assert.Equal(t, RedrivePolicy{}, cqr.Attributes.RedrivePolicy) - assert.Equal(t, map[string]interface{}(nil), cqr.Attributes.RedriveAllowPolicy) -} - -func TestNewCreateTopicRequest(t *testing.T) { - defer func() { - ResetApp() - }() - - result := NewCreateTopicRequest() - - assert.Equal(t, false, result.Attributes.FifoTopic) - assert.Equal(t, StringToInt(1), result.Attributes.SignatureVersion) - assert.Equal(t, "Active", result.Attributes.TracingConfig) - assert.Equal(t, false, result.Attributes.ContentBasedDeduplication) -} - -func TestCreateTopicRequest_SetAttributesFromForm_success(t *testing.T) { - form := url.Values{} - form.Add("Action", "CreateQueue") - form.Add("QueueName", "new-queue") - form.Add("Version", "2012-11-05") - form.Add("Attribute.1.Name", "DeliveryPolicy") - form.Add("Attribute.1.Value", "{\"i-am\":\"the-policy\", \"name\":\"delivery-policy\"}") - form.Add("Attribute.2.Name", "DisplayName") - form.Add("Attribute.2.Value", "Foo") - form.Add("Attribute.3.Name", "FifoTopic") - form.Add("Attribute.3.Value", "true") - form.Add("Attribute.4.Name", "Policy") - form.Add("Attribute.4.Value", "{\"i-am\":\"the-policy\", \"name\":\"policy\"}") - form.Add("Attribute.5.Name", "SignatureVersion") - form.Add("Attribute.5.Value", "99") - form.Add("Attribute.6.Name", "TracingConfig") - form.Add("Attribute.6.Value", "PassThrough") - form.Add("Attribute.7.Name", "KmsMasterKeyId") - form.Add("Attribute.7.Value", "1234abcd-12ab-34cd-56ef-1234567890ab") - form.Add("Attribute.8.Name", "ArchivePolicy") - form.Add("Attribute.8.Value", "{\"i-am\":\"the-policy\", \"name\":\"archive-policy\"}") - form.Add("Attribute.9.Name", "BeginningArchiveTime") - form.Add("Attribute.9.Value", "2024-07-01T23:59:59+09:00") - form.Add("Attribute.10.Name", "ContentBasedDeduplication") - form.Add("Attribute.10.Value", "true") - - ctr := &CreateTopicRequest{} - ctr.SetAttributesFromForm(form) - - assert.Equal(t, 2, len(ctr.Attributes.DeliveryPolicy)) - assert.Equal(t, "the-policy", ctr.Attributes.DeliveryPolicy["i-am"]) - assert.Equal(t, "delivery-policy", ctr.Attributes.DeliveryPolicy["name"]) - assert.Equal(t, "Foo", ctr.Attributes.DisplayName) - assert.Equal(t, true, ctr.Attributes.FifoTopic) - assert.Equal(t, 2, len(ctr.Attributes.Policy)) - assert.Equal(t, "the-policy", ctr.Attributes.Policy["i-am"]) - assert.Equal(t, "policy", ctr.Attributes.Policy["name"]) - assert.Equal(t, StringToInt(99), ctr.Attributes.SignatureVersion) - assert.Equal(t, "PassThrough", ctr.Attributes.TracingConfig) - assert.Equal(t, "1234abcd-12ab-34cd-56ef-1234567890ab", ctr.Attributes.KmsMasterKeyId) - assert.Equal(t, 2, len(ctr.Attributes.ArchivePolicy)) - assert.Equal(t, "the-policy", ctr.Attributes.ArchivePolicy["i-am"]) - assert.Equal(t, "archive-policy", ctr.Attributes.ArchivePolicy["name"]) - assert.Equal(t, "2024-07-01T23:59:59+09:00", ctr.Attributes.BeginningArchiveTime) - assert.Equal(t, true, ctr.Attributes.ContentBasedDeduplication) -} - -func TestSubscribeRequest_SetAttributesFromForm_success(t *testing.T) { - form := url.Values{} - form.Add("Attributes.entry.1.key", "RawMessageDelivery") - form.Add("Attributes.entry.1.value", "true") - form.Add("Attributes.entry.2.key", "FilterPolicy") - form.Add("Attributes.entry.2.value", "{\"filter\": [\"policy\"]}") - - cqr := &SubscribeRequest{ - Attributes: SubscriptionAttributes{}, - } - cqr.SetAttributesFromForm(form) - - assert.True(t, cqr.Attributes.RawMessageDelivery) - assert.Equal(t, FilterPolicy{"filter": []string{"policy"}}, cqr.Attributes.FilterPolicy) -} - -func TestSubscribeRequest_SetAttributesFromForm_skips_invalid_values(t *testing.T) { - form := url.Values{} - form.Add("Attributes.entry.1.key", "RawMessageDelivery") - form.Add("Attributes.entry.1.value", "garbage") - form.Add("Attributes.entry.2.key", "FilterPolicy") - form.Add("Attributes.entry.2.value", "also-garbage") - - cqr := &SubscribeRequest{ - Attributes: SubscriptionAttributes{}, - } - cqr.SetAttributesFromForm(form) - - assert.False(t, cqr.Attributes.RawMessageDelivery) - assert.Equal(t, FilterPolicy(nil), cqr.Attributes.FilterPolicy) -} - -func TestSubscribeRequest_SetAttributesFromForm_stops_if_attributes_not_numbered_sequentially(t *testing.T) { - form := url.Values{} - form.Add("Attributes.entry.2.key", "RawMessageDelivery") - form.Add("Attributes.entry.2.value", "garbage") - form.Add("Attributes.entry.3.key", "FilterPolicy") - form.Add("Attributes.entry.3.value", "also-garbage") - - cqr := &SubscribeRequest{ - Attributes: SubscriptionAttributes{}, - } - cqr.SetAttributesFromForm(form) - - assert.False(t, cqr.Attributes.RawMessageDelivery) - assert.Equal(t, FilterPolicy(nil), cqr.Attributes.FilterPolicy) -} - -func Test_DeleteMessageBatchRequest_SetAttributesFromForm_success(t *testing.T) { - form := url.Values{} - form.Add("DeleteMessageBatchRequestEntry.1.Id", "message-id-1") - form.Add("DeleteMessageBatchRequestEntry.1.ReceiptHandle", "receipt-handle-1") - form.Add("DeleteMessageBatchRequestEntry.2.Id", "message-id-2") - form.Add("DeleteMessageBatchRequestEntry.2.ReceiptHandle", "receipt-handle-2") - form.Add("DeleteMessageBatchRequestEntry.3.Id", "message-id-3") - form.Add("DeleteMessageBatchRequestEntry.3.ReceiptHandle", "receipt-handle-3") - - dmbr := &DeleteMessageBatchRequest{} - dmbr.SetAttributesFromForm(form) - - assert.Len(t, dmbr.Entries, 3) - assert.Equal(t, "message-id-1", dmbr.Entries[0].Id) - assert.Equal(t, "receipt-handle-1", dmbr.Entries[0].ReceiptHandle) - assert.Equal(t, "message-id-2", dmbr.Entries[1].Id) - assert.Equal(t, "receipt-handle-2", dmbr.Entries[1].ReceiptHandle) - assert.Equal(t, "message-id-3", dmbr.Entries[2].Id) - assert.Equal(t, "receipt-handle-3", dmbr.Entries[2].ReceiptHandle) -} - -func Test_DeleteMessageBatchRequest_SetAttributesFromForm_stops_at_non_sequential_keys(t *testing.T) { - form := url.Values{} - form.Add("DeleteMessageBatchRequestEntry.1.Id", "message-id-1") - form.Add("DeleteMessageBatchRequestEntry.1.ReceiptHandle", "receipt-handle-1") - form.Add("DeleteMessageBatchRequestEntry.4.Id", "message-id-2") - form.Add("DeleteMessageBatchRequestEntry.4.ReceiptHandle", "receipt-handle-2") - form.Add("DeleteMessageBatchRequestEntry.3.Id", "message-id-3") - form.Add("DeleteMessageBatchRequestEntry.3.ReceiptHandle", "receipt-handle-3") - - dmbr := &DeleteMessageBatchRequest{} - dmbr.SetAttributesFromForm(form) - - assert.Len(t, dmbr.Entries, 1) - assert.Equal(t, "message-id-1", dmbr.Entries[0].Id) - assert.Equal(t, "receipt-handle-1", dmbr.Entries[0].ReceiptHandle) -} - -func Test_DeleteMessageBatchRequest_SetAttributesFromForm_stops_at_invalid_keys(t *testing.T) { - form := url.Values{} - form.Add("DeleteMessageBatchRequestEntry.1.Id", "message-id-1") - form.Add("DeleteMessageBatchRequestEntry.1.ReceiptHandle", "receipt-handle-1") - form.Add("INVALID_DeleteMessageBatchRequestEntry.2.Id", "message-id-2") - form.Add("DeleteMessageBatchRequestEntry.2.ReceiptHandle", "receipt-handle-2") - form.Add("DeleteMessageBatchRequestEntry.3.Id", "message-id-3") - form.Add("DeleteMessageBatchRequestEntry.3.ReceiptHandle", "receipt-handle-3") - - dmbr := &DeleteMessageBatchRequest{} - dmbr.SetAttributesFromForm(form) - - assert.Len(t, dmbr.Entries, 1) - assert.Equal(t, "message-id-1", dmbr.Entries[0].Id) - assert.Equal(t, "receipt-handle-1", dmbr.Entries[0].ReceiptHandle) -} - -func TestPublishRequest_SetAttributesFromForm_success_concurrent(t *testing.T) { - form := url.Values{} - form.Add("MessageAttributes.entry.1.Name", "test1") - form.Add("MessageAttributes.entry.1.Value.DataType", "String") - form.Add("MessageAttributes.entry.1.Value.StringValue", "sample-string") - form.Add("MessageAttributes.entry.2.Name", "test2") - form.Add("MessageAttributes.entry.2.Value.DataType", "Binary") - form.Add("MessageAttributes.entry.2.Value.BinaryValue", "YmluYXJ5LXZhbHVl") - - // if the code is not thread-safe, repeated runs increase the chance of detecting a race. - for r := 0; r < 10; r++ { - var wg sync.WaitGroup - goroutineCount := 40 - // launch goroutines in parallel to simulate concurrent access. - for g := 0; g < goroutineCount; g++ { - wg.Add(1) - go func() { - defer wg.Done() - // introduce a random delay to encourage goroutine interleaving - time.Sleep(time.Duration(rand.Intn(5)) * time.Millisecond) - cqr := &PublishRequest{ - MessageAttributes: make(map[string]MessageAttribute), - } - - cqr.SetAttributesFromForm(form) - - // validate the expected DataType values - assert.Equal(t, "String", cqr.MessageAttributes["test1"].DataType) - assert.Equal(t, "Binary", cqr.MessageAttributes["test2"].DataType) - }() - } - wg.Wait() - } -} - -func TestParseMessageAttributes(t *testing.T) { - for _, tc := range []struct { - description string - values url.Values - keyPrefix string - want map[string]MessageAttribute - }{ - { - description: "empty", - values: url.Values{}, - keyPrefix: "foo", - want: nil, - }, - { - description: "simple", - values: url.Values{ - "MessageAttribute.1.Name": []string{"Attr1"}, - "MessageAttribute.1.Value.DataType": []string{"String"}, - "MessageAttribute.1.Value.StringValue": []string{"Value1"}, - "MessageAttribute.2.Name": []string{"Attr2"}, - "MessageAttribute.2.Value.DataType": []string{"Binary"}, - "MessageAttribute.2.Value.BinaryValue": []string{"VmFsdWUy"}, - }, - keyPrefix: "MessageAttribute", - want: map[string]MessageAttribute{ - "Attr1": { - DataType: "String", - StringValue: "Value1", - BinaryValue: "", - }, - "Attr2": { - DataType: "Binary", - BinaryValue: "VmFsdWUy", - }, - }, - }, - { - description: "attributes after empty name ignored", - values: url.Values{ - "MessageAttribute.1.Name": []string{""}, - "MessageAttribute.1.Value.DataType": []string{"String"}, - "MessageAttribute.1.Value.StringValue": []string{"Value4"}, - "MessageAttribute.2.Name": []string{"Attr2"}, - "MessageAttribute.2.Value.DataType": []string{"Binary"}, - "MessageAttribute.2.Value.BinaryValue": []string{"VmFsdWUy"}, - }, - keyPrefix: "MessageAttribute", - want: nil, - }, - { - description: "attributes after missing number ignored", - values: url.Values{ - // Note starting from 2 - "MessageAttribute.2.Name": []string{"Attr2"}, - "MessageAttribute.2.Value.DataType": []string{"Binary"}, - "MessageAttribute.2.Value.BinaryValue": []string{"VmFsdWUy"}, - }, - keyPrefix: "MessageAttribute", - want: nil, - }, - { - description: "empty DataType ignored", - values: url.Values{ - "MessageAttribute.1.Name": []string{"Attr4"}, - "MessageAttribute.1.Value.DataType": []string{""}, - "MessageAttribute.1.Value.StringValue": []string{"Value4"}, - }, - keyPrefix: "MessageAttribute", - want: nil, - }, - } { - t.Run(tc.description, func(t *testing.T) { - got := parseMessageAttributes(tc.values, tc.keyPrefix) - assert.Equal(t, tc.want, got) - }) - } -} diff --git a/app/router/router_test.go b/app/router/router_test.go deleted file mode 100644 index dd06773..0000000 --- a/app/router/router_test.go +++ /dev/null @@ -1,251 +0,0 @@ -package router - -import ( - "bytes" - "encoding/json" - "encoding/xml" - "fmt" - "net/http" - "net/http/httptest" - "net/url" - "strings" - "testing" - - af "shared-sqs/app/fixtures" - - "shared-sqs/app/mocks" - - "shared-sqs/app/interfaces" - - sqs "shared-sqs/app/gosqs" - - "github.com/stretchr/testify/assert" - - "shared-sqs/app/test" -) - -func TestIndexServerhandler_POST_BadRequest(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. - req, err := http.NewRequest("POST", "/", nil) - if err != nil { - t.Fatal(err) - } - - form := url.Values{} - form.Add("Action", "BadRequest") - req.PostForm = form - - // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response. - rr := httptest.NewRecorder() - - // Our handlers satisfy http.Handler, so we can call their ServeHTTP method - // directly and pass in our Request and ResponseRecorder. - New().ServeHTTP(rr, req) - - // Check the status code is what we expect. - if status := rr.Code; status != http.StatusBadRequest { - t.Errorf("handler returned wrong status code: got %v want %v", - status, http.StatusOK) - } -} - -func TestIndexServerhandler_POST_GoodRequest(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. - req, err := http.NewRequest("POST", "/", nil) - if err != nil { - t.Fatal(err) - } - - form := url.Values{} - form.Add("Action", "ListTopics") - req.PostForm = form - - // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response. - rr := httptest.NewRecorder() - - // Our handlers satisfy http.Handler, so we can call their ServeHTTP method - // directly and pass in our Request and ResponseRecorder. - New().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) - } -} - -func TestIndexServerhandler_POST_GoodRequest_With_URL(t *testing.T) { - req, err := http.NewRequest("POST", "/100010001000/local-queue1", nil) - if err != nil { - t.Fatal(err) - } - - form := url.Values{} - form.Add("Action", "CreateQueue") - form.Add("QueueName", "local-queue1") - req.PostForm = form - rr := httptest.NewRecorder() - New().ServeHTTP(rr, req) - - form = url.Values{} - form.Add("Action", "GetQueueAttributes") - form.Add("QueueUrl", fmt.Sprintf("%s/local-queue1", af.BASE_URL)) - req.PostForm = form - - // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response. - rr = httptest.NewRecorder() - - // Our handlers satisfy http.Handler, so we can call their ServeHTTP method - // directly and pass in our Request and ResponseRecorder. - New().ServeHTTP(rr, req) - - assert.Equal(t, http.StatusOK, rr.Code) -} - -func TestIndexServerhandler_POST_GoodRequest_With_URL_And_Aws_Json_Protocol(t *testing.T) { - json, _ := json.Marshal(map[string]string{ - "QueueName": "local-queue1", - }) - req, err := http.NewRequest("POST", "/100010001000/local-queue1", bytes.NewBuffer(json)) - if err != nil { - t.Fatal(err) - } - req.Header.Set("X-Amz-Target", "AmazonSQS.CreateQueue") - req.Header.Set("Content-Type", "application/x-amz-json-1.0") - - rr := httptest.NewRecorder() - - New().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) - } -} - -func TestIndexServerhandler_GET_GoodRequest_Pem_cert(t *testing.T) { - - req, err := http.NewRequest("GET", "/SimpleNotificationService/100010001000.pem", nil) - if err != nil { - t.Fatal(err) - } - - rr := httptest.NewRecorder() - New().ServeHTTP(rr, req) - - if status := rr.Code; status != http.StatusOK { - t.Errorf("handler returned wrong status code: got %v want %v", - status, http.StatusOK) - } -} - -func TestEncodeResponse_success_xml(t *testing.T) { - w, r := test.GenerateRequestInfo("POST", "/url", nil, false) - - encodeResponse(w, r, http.StatusOK, mocks.BaseResponse{Message: "test"}) - - assert.Equal(t, http.StatusOK, w.Code) - - tmp := mocks.BaseResponse{} - xml.Unmarshal(w.Body.Bytes(), &tmp) - assert.Equal(t, mocks.BaseResponse{Message: "test"}, tmp) -} - -func TestEncodeResponse_success_skips_nil_body_xml(t *testing.T) { - w, r := test.GenerateRequestInfo("POST", "/url", nil, false) - - encodeResponse(w, r, http.StatusOK, nil) - - assert.Equal(t, http.StatusOK, w.Code) - assert.Equal(t, &bytes.Buffer{}, w.Body) -} - -func TestEncodeResponse_success_json(t *testing.T) { - w, r := test.GenerateRequestInfo("POST", "/url", nil, true) - - encodeResponse(w, r, http.StatusOK, mocks.BaseResponse{Message: "test"}) - - assert.Equal(t, http.StatusOK, w.Code) - - tmp := mocks.BaseResponse{} - json.Unmarshal(w.Body.Bytes(), &tmp) - assert.Equal(t, mocks.BaseResponse{Message: "test"}, tmp) -} - -func TestEncodeResponse_success_skips_malformed_body_json(t *testing.T) { - mock := mocks.BaseResponse{ - Message: "test", - } - mock.MockGetResult = func() interface{} { - return make(chan int) - } - w, r := test.GenerateRequestInfo("POST", "/url", nil, true) - - encodeResponse(w, r, http.StatusOK, mock) - - assert.Equal(t, http.StatusOK, w.Code) - assert.Equal(t, "General Error", strings.TrimSpace(string(w.Body.Bytes()))) -} - -func TestActionHandler_v1_json(t *testing.T) { - defer func() { - routingTableV1 = map[string]func(r *http.Request) (int, interfaces.AbstractResponseBody){ - "CreateQueue": sqs.CreateQueueV1, - } - }() - - mockCalled := false - mockFunction := func(req *http.Request) (int, interfaces.AbstractResponseBody) { - mockCalled = true - return http.StatusOK, mocks.BaseResponse{Message: "response-body"} - } - routingTableV1 = map[string]func(r *http.Request) (int, interfaces.AbstractResponseBody){ - "CreateQueue": mockFunction, - } - - w, r := test.GenerateRequestInfo("POST", "/url", nil, true) - r.Header.Set("X-Amz-Target", "QueueService.CreateQueue") - - actionHandler(w, r) - - assert.True(t, mockCalled) - assert.Equal(t, http.StatusOK, w.Code) - - tmp := mocks.BaseResponse{} - json.Unmarshal(w.Body.Bytes(), &tmp) - assert.Equal(t, mocks.BaseResponse{Message: "response-body"}, tmp) -} - -func TestActionHandler_v1_xml(t *testing.T) { - defer func() { - routingTableV1 = map[string]func(r *http.Request) (int, interfaces.AbstractResponseBody){ - "CreateQueue": sqs.CreateQueueV1, - } - }() - - mockCalled := false - mockFunction := func(req *http.Request) (int, interfaces.AbstractResponseBody) { - mockCalled = true - return http.StatusOK, mocks.BaseResponse{Message: "response-body"} - } - routingTableV1 = map[string]func(r *http.Request) (int, interfaces.AbstractResponseBody){ - "CreateQueue": mockFunction, - } - - w, r := test.GenerateRequestInfo("POST", "/url", nil, false) - form := url.Values{} - form.Add("Action", "CreateQueue") - r.PostForm = form - - actionHandler(w, r) - - assert.True(t, mockCalled) - assert.Equal(t, http.StatusOK, w.Code) - - tmp := mocks.BaseResponse{} - xml.Unmarshal(w.Body.Bytes(), &tmp) - assert.Equal(t, mocks.BaseResponse{Message: "response-body"}, tmp) -} diff --git a/app/utils/utils_test.go b/app/utils/utils_test.go deleted file mode 100644 index 72e978d..0000000 --- a/app/utils/utils_test.go +++ /dev/null @@ -1,139 +0,0 @@ -package utils - -import ( - "net/url" - "testing" - - "shared-sqs/app/models" - - "shared-sqs/app/test" - - "shared-sqs/app/fixtures" - "shared-sqs/app/mocks" - - "github.com/stretchr/testify/assert" -) - -func TestTransformRequest_success_json(t *testing.T) { - _, r := test.GenerateRequestInfo("POST", "url", fixtures.JSONRequestBody, true) - - mock := &mocks.MockRequestBody{} - - ok := TransformRequest(mock, r, false) - - assert.True(t, ok) - assert.Equal(t, "mock-value", mock.RequestFieldStr) - assert.False(t, mock.SetAttributesFromFormCalled) -} - -func TestTransformRequest_success_json_empty_request_accepted(t *testing.T) { - _, r := test.GenerateRequestInfo("POST", "url", nil, true) - - mock := &mocks.MockRequestBody{} - - ok := TransformRequest(mock, r, true) - - assert.True(t, ok) - //assert.Equal(t, "mock-value", mock.RequestFieldStr) - assert.False(t, mock.SetAttributesFromFormCalled) -} - -func TestTransformRequest_success_xml(t *testing.T) { - _, r := test.GenerateRequestInfo("POST", "url", nil, false) - form := url.Values{} - form.Add("Action", "CreateQueue") - form.Add("QueueName", "UnitTestQueue1") - form.Add("Attribute.1.Name", "VisibilityTimeout") - form.Add("Attribute.1.Value", "60") - form.Add("Attribute.2.Name", "MaximumMessageSize") - form.Add("Attribute.2.Value", "2048") - r.PostForm = form - - mock := &mocks.MockRequestBody{} - - ok := TransformRequest(mock, r, false) - - assert.True(t, ok) - assert.True(t, mock.SetAttributesFromFormCalled) - assert.Equal(t, []interface{}{form}, mock.SetAttributesFromFormCalledWith) -} - -func TestTransformRequest_error_invalid_request_body_json(t *testing.T) { - _, r := test.GenerateRequestInfo("POST", "url", "\"I-am-garbage", true) - - mock := &mocks.MockRequestBody{} - - ok := TransformRequest(mock, r, false) - - assert.False(t, ok) - assert.Equal(t, "", mock.RequestFieldStr) - assert.False(t, mock.SetAttributesFromFormCalled) -} - -func TestTransformRequest_error_failure_to_parse_form_xml(t *testing.T) { - _, r := test.GenerateRequestInfo("POST", "url", nil, false) - - mock := &mocks.MockRequestBody{} - - ok := TransformRequest(mock, r, false) - - assert.False(t, ok) - assert.False(t, mock.SetAttributesFromFormCalled) -} - -func TestTransformRequest_error_invalid_request_body_xml(t *testing.T) { - _, r := test.GenerateRequestInfo("POST", "url", nil, false) - - form := url.Values{} - form.Add("intField", "\"I-am-garbage") - r.PostForm = form - - mock := &mocks.MockRequestBody{} - - ok := TransformRequest(mock, r, false) - - assert.False(t, ok) - assert.False(t, mock.SetAttributesFromFormCalled) -} - -func TestExtractQueueAttributes_success(t *testing.T) { - u := url.Values{} - u.Add("Attribute.1.Name", "DelaySeconds") - u.Add("Attribute.1.Value", "20") - u.Add("Attribute.2.Name", "VisibilityTimeout") - u.Add("Attribute.2.Value", "30") - u.Add("Attribute.3.Name", "Policy") - - attr := ExtractQueueAttributes(u) - expected := map[string]string{ - "DelaySeconds": "20", - "VisibilityTimeout": "30", - } - - assert.Equal(t, expected, attr) -} - -func TestGetMD5Hash(t *testing.T) { - hash1 := GetMD5Hash("This is a test") - hash2 := GetMD5Hash("This is a test") - if hash1 != hash2 { - t.Errorf("hashs and hash2 should be the same, but were not") - } - - hash1 = GetMD5Hash("This is a test") - hash2 = GetMD5Hash("This is a tfst") - if hash1 == hash2 { - t.Errorf("hashs and hash2 are the same, but should not be") - } -} - -func TestSortedKeys(t *testing.T) { - attributes := map[string]models.MessageAttribute{ - "b": {}, - "a": {}, - } - - keys := sortedKeys(attributes) - assert.Equal(t, "a", keys[0]) - assert.Equal(t, "b", keys[1]) -}