diff --git a/internal/usecases/consume/consume_test.go b/internal/usecases/consume/consume_test.go index cac617b6e0479c2791f64a9730c4a2d316fa4212..ecdf68ca73a28eb01d013c50f6e1f30433768451 100644 --- a/internal/usecases/consume/consume_test.go +++ b/internal/usecases/consume/consume_test.go @@ -27,21 +27,22 @@ type testSuite struct { service *Service } -// Reset all stateful things -func (ts *testSuite) reset() { - // Reset broker messages - ts.mockBroker.Messages = make(map[string][]broker.Message) -} +var ts *testSuite + +func createTestSuite() { + if ts != nil { + ts.reset() + return + } -func TestHandleMessages(t *testing.T) { // Create test suite mockBroker := broker.NewMockDriver().(*broker.MockDriver) mockKeyValueStore := keyvaluestore.NewMockDriver() - ts := testSuite{ + ts = &testSuite{ mockBroker: mockBroker, mockKeyValueStore: mockKeyValueStore, produceService: produce.NewService(mockBroker, mockKeyValueStore), - queryConverter: aql.NewMockService(), + queryConverter: aql.NewService(), requestSenderService: mockrequest.NewService(), databaseInfoService: mockdatabaseinfo.NewService(), } @@ -52,152 +53,234 @@ func TestHandleMessages(t *testing.T) { // Start producer ts.produceService.Start() +} - // Run tests using the test suite - t.Run("correct message", func(t *testing.T) { - // Reset possible state - ts.reset() +// Reset all stateful things +func (ts *testSuite) reset() { + // Reset broker messages + ts.mockBroker.Messages = make(map[string][]broker.Message) +} - // Create a mock message - headers := make(map[string]interface{}) - headers["sessionID"] = "mock-session" - headers["clientID"] = "mock-client" - mockMessage := broker.Message{ - Headers: headers, - Body: []byte(`{ - "databaseName": "test", - "return": { - "entities": [], - "relations": [] - }, - "entities": [], - "relations": [], - "limit": 5000 - }`), - } - - // Assert that there have not been any messages sent yet - assert.Empty(t, mockBroker.Messages) - - // Send the mock message - ts.service.HandleMessage(&mockMessage) - - // Assert that there now are two messages that have been sent with routing key mock-queue - assert.Len(t, mockBroker.Messages["mock-queue"], 2) - - // Assert that the first message is of type 'query_translation_result' and has 'Query converted' as value - var translationMessage entity.MessageStruct - json.Unmarshal(mockBroker.Messages["mock-queue"][0].Body, &translationMessage) - assert.Equal(t, "query_translation_result", translationMessage.Type) - assert.Equal(t, "Query converted", translationMessage.Value) - - // Assert that the second message is of type 'query_result' and contains no values - var resultMessage entity.MessageStruct - json.Unmarshal(mockBroker.Messages["mock-queue"][1].Body, &resultMessage) - assert.Equal(t, "query_result", resultMessage.Type) - assert.Equal(t, "test", resultMessage.Value) - }) - - t.Run("no session id", func(t *testing.T) { - // Reset possible state - ts.reset() +func TestCorrectMessageHandled(t *testing.T) { + createTestSuite() - // Create a mock message - headers := make(map[string]interface{}) - headers["clientID"] = "mock-client" - mockMessage := broker.Message{ - Headers: headers, - Body: []byte(`{ - "databaseName": "test", - "return": { - "entities": [], - "relations": [] - }, + // Create a mock message + headers := make(map[string]interface{}) + headers["sessionID"] = "mock-session" + headers["clientID"] = "mock-client" + mockMessage := broker.Message{ + Headers: headers, + Body: []byte(`{ + "databaseName": "test", + "return": { "entities": [], - "relations": [], - "limit": 5000 - }`), - } + "relations": [] + }, + "entities": [], + "relations": [], + "limit": 5000 + }`), + } - // Assert that there have not been any messages sent yet - assert.Empty(t, mockBroker.Messages) + // Assert that there have not been any messages sent yet + assert.Empty(t, ts.mockBroker.Messages) - // Send the mock message - ts.service.HandleMessage(&mockMessage) + // Send the mock message + ts.service.HandleMessage(&mockMessage) - // Assert that there was no message published - assert.Empty(t, mockBroker.Messages) - }) + // Assert that there now are two messages that have been sent with routing key mock-queue + assert.Len(t, ts.mockBroker.Messages["mock-queue"], 2) - t.Run("failure to unmarshal JSON query", func(t *testing.T) { - // Reset possible state - ts.reset() + // Assert that the first message is of type 'query_translation_result' and has 'Query converted' as value + var translationMessage entity.MessageStruct + json.Unmarshal(ts.mockBroker.Messages["mock-queue"][0].Body, &translationMessage) + assert.Equal(t, "query_translation_result", translationMessage.Type) - // Create a mock message - headers := make(map[string]interface{}) - headers["clientID"] = "mock-client" - headers["sessionID"] = "mock-session" - mockMessage := broker.Message{ - Headers: headers, - Body: []byte(`{ - "databaseName": "test", - "return": { - "entities": [], - "relations": [] - }, - "entities": [], - "relations": [], - "limit": "test" - }`), - } - - // Assert that there have not been any messages sent yet - assert.Empty(t, mockBroker.Messages) - - // Send the mock message - ts.service.HandleMessage(&mockMessage) - - // Assert that there was an error message published - var errorMsg entity.MessageStruct - json.Unmarshal(mockBroker.Messages["mock-queue"][0].Body, &errorMsg) - assert.Equal(t, "query_translation_error", errorMsg.Type) - }) - - // MARK: test - t.Run("database execution error", func(t *testing.T) { - // Reset possible state - ts.reset() + // Assert that the second message is of type 'query_result' and contains no values + var resultMessage entity.MessageStruct + json.Unmarshal(ts.mockBroker.Messages["mock-queue"][1].Body, &resultMessage) + assert.Equal(t, "query_result", resultMessage.Type) + assert.Equal(t, "test", resultMessage.Value) +} - // Create a mock message - headers := make(map[string]interface{}) - headers["clientID"] = "mock-client" - headers["sessionID"] = "mock-session" - mockMessage := broker.Message{ - Headers: headers, - Body: []byte(`{ - "databaseName": "test", - "return": { - "entities": [], - "relations": [] - }, - "entities": [], - "relations": [], - "limit": 5000 - }`), - } +func TestNoSessionIDHandled(t *testing.T) { + createTestSuite() + + // Create a mock message + headers := make(map[string]interface{}) + headers["clientID"] = "mock-client" + mockMessage := broker.Message{ + Headers: headers, + Body: []byte(`{ + "databaseName": "test", + "return": { + "entities": [], + "relations": [] + }, + "entities": [], + "relations": [], + "limit": 5000 + }`), + } - // Make it so that the request sender service throws an error - ts.requestSenderService.ToggleError() + // Assert that there have not been any messages sent yet + assert.Empty(t, ts.mockBroker.Messages) + + // Send the mock message + ts.service.HandleMessage(&mockMessage) + + // Assert that there was no message published + assert.Empty(t, ts.mockBroker.Messages) +} + +func TestBadIncomingQueryHandled(t *testing.T) { + createTestSuite() + + // Create a mock message + headers := make(map[string]interface{}) + headers["clientID"] = "mock-client" + headers["sessionID"] = "mock-session" + mockMessage := broker.Message{ + Headers: headers, + Body: []byte(`{ + "databaseName": "test", + "return": { + "entities": [], + "relations": [] + }, + "entities": [], + "relations": [], + "limit": "test" + }`), + } + + // Assert that there have not been any messages sent yet + assert.Empty(t, ts.mockBroker.Messages) + + // Send the mock message + ts.service.HandleMessage(&mockMessage) + + // Assert that there was an error message published + var errorMsg entity.MessageStruct + json.Unmarshal(ts.mockBroker.Messages["mock-queue"][0].Body, &errorMsg) + assert.Equal(t, "query_translation_error", errorMsg.Type) +} + +func TestDatabaseErrorHandled(t *testing.T) { + createTestSuite() + + // Create a mock message + headers := make(map[string]interface{}) + headers["clientID"] = "mock-client" + headers["sessionID"] = "mock-session" + mockMessage := broker.Message{ + Headers: headers, + Body: []byte(`{ + "databaseName": "test", + "return": { + "entities": [], + "relations": [] + }, + "entities": [], + "relations": [], + "limit": 5000 + }`), + } + + // Make it so that the request sender service throws an error + ts.requestSenderService.ToggleError() + + // Assert that there have not been any messages sent yet + assert.Empty(t, ts.mockBroker.Messages) + + // Send the mock message + ts.service.HandleMessage(&mockMessage) + + // Assert that there was an error message published + var errorMsg entity.MessageStruct + json.Unmarshal(ts.mockBroker.Messages["mock-queue"][1].Body, &errorMsg) + assert.Equal(t, "query_database_error", errorMsg.Type) + + // Turn of error throwing in request service + ts.requestSenderService.ToggleError() +} + +func TestQueryConversionErrorHandled(t *testing.T) { + createTestSuite() + + // Create a mock message + headers := make(map[string]interface{}) + headers["clientID"] = "mock-client" + headers["sessionID"] = "mock-session" + mockMessage := broker.Message{ + Headers: headers, + Body: []byte(`{ + "databaseName": "test", + "return": { + "entities": [ + 1 + ], + "relations": [] + }, + "entities": [ + { + "type": "airports", + "constraints": [ + { + "attribute": "state", + "value": "HI", + "dataType": "text", + "matchType": "exact" + } + ] + } + ], + "relations": [], + "limit": 5000 + }`), + } + + // Assert that there have not been any messages sent yet + assert.Empty(t, ts.mockBroker.Messages) + + // Send the mock message + ts.service.HandleMessage(&mockMessage) + + // Assert that there was an error message published + var errorMsg entity.MessageStruct + json.Unmarshal(ts.mockBroker.Messages["mock-queue"][0].Body, &errorMsg) + assert.Equal(t, "query_translation_error", errorMsg.Type) +} + +func TestNoDatabaseNameHandled(t *testing.T) { + createTestSuite() + + // Create a mock message + headers := make(map[string]interface{}) + headers["clientID"] = "mock-client" + headers["sessionID"] = "mock-session" + mockMessage := broker.Message{ + Headers: headers, + Body: []byte(`{ + "return": { + "entities": [], + "relations": [] + }, + "entities": [], + "relations": [], + "limit": 5000 + }`), + } - // Assert that there have not been any messages sent yet - assert.Empty(t, mockBroker.Messages) + // Assert that there have not been any messages sent yet + assert.Empty(t, ts.mockBroker.Messages) - // Send the mock message - ts.service.HandleMessage(&mockMessage) + // Send the mock message + ts.service.HandleMessage(&mockMessage) - // Assert that there was an error message published - var errorMsg entity.MessageStruct - json.Unmarshal(mockBroker.Messages["mock-queue"][1].Body, &errorMsg) - assert.Equal(t, "query_database_error", errorMsg.Type) - }) + // Assert that there was an error message published + var errorMsg entity.MessageStruct + json.Unmarshal(ts.mockBroker.Messages["mock-queue"][0].Body, &errorMsg) + assert.Equal(t, "query_malformed_request_error", errorMsg.Type) + assert.Equal(t, "no database name supplied", errorMsg.Value) } diff --git a/internal/usecases/consume/handlemessage.go b/internal/usecases/consume/handlemessage.go index 44bd65492361622c8dd3212e3f7ba6a0ffc7b3a7..7efd3af47633b420455712fa7c152045157d96da 100644 --- a/internal/usecases/consume/handlemessage.go +++ b/internal/usecases/consume/handlemessage.go @@ -35,23 +35,23 @@ func (s *Service) HandleMessage(msg *broker.Message) { return } - // Convert the json byte msg to a query string - query, err := s.queryConverter.ConvertQuery(JSONQuery) - if err != nil { + // Check if there was a database name + if JSONQuery.DatabaseName == "" { errorMsg := entity.MessageStruct{ - Type: "query_translation_error", - Value: err.Error(), + Type: "query_malformed_request_error", + Value: "no database name supplied", } errorMsgBytes, _ := json.Marshal(errorMsg) s.producer.PublishMessage(&errorMsgBytes, &sessionID) return } - // Check if there was a database name - if JSONQuery.DatabaseName == "" { + // Convert the json byte msg to a query string + query, err := s.queryConverter.ConvertQuery(JSONQuery) + if err != nil { errorMsg := entity.MessageStruct{ - Type: "query_malformed_request_error", - Value: "no database name supplied", + Type: "query_translation_error", + Value: err.Error(), } errorMsgBytes, _ := json.Marshal(errorMsg) s.producer.PublishMessage(&errorMsgBytes, &sessionID)