<commit_before>/**
*  Copyright (C) 2015 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 of the
*  License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <gtest/gtest.h>
#include <repo/core/handler/repo_database_handler_mongo.h>
#include "../../../repo_test_database_info.h"

using namespace repo::core::handler;

MongoDatabaseHandler* getHandler()
{
	std::string errMsg;
	return 	MongoDatabaseHandler::getHandler(errMsg, REPO_GTEST_DBADDRESS, REPO_GTEST_DBPORT,
		1,
		REPO_GTEST_AUTH_DATABASE,
		REPO_GTEST_DBUSER, REPO_GTEST_DBPW);
}

TEST(MongoDatabaseHandlerTest, GetHandlerDisconnectHandler)
{

	std::string errMsg;
	MongoDatabaseHandler* handler =
		MongoDatabaseHandler::getHandler(errMsg, REPO_GTEST_DBADDRESS, REPO_GTEST_DBPORT,
		1,
		REPO_GTEST_AUTH_DATABASE, 
		REPO_GTEST_DBUSER, REPO_GTEST_DBPW);

	EXPECT_TRUE(handler);
	EXPECT_TRUE(errMsg.empty());

	EXPECT_TRUE(MongoDatabaseHandler::getHandler(REPO_GTEST_DBADDRESS));
	MongoDatabaseHandler::disconnectHandler();

	EXPECT_FALSE(MongoDatabaseHandler::getHandler(REPO_GTEST_DBADDRESS));

	MongoDatabaseHandler *wrongAdd = MongoDatabaseHandler::getHandler(errMsg, "blah", REPO_GTEST_DBPORT,
		1,
		REPO_GTEST_AUTH_DATABASE,
		REPO_GTEST_DBUSER, REPO_GTEST_DBPW);

	EXPECT_FALSE(wrongAdd);
	MongoDatabaseHandler *wrongPort = MongoDatabaseHandler::getHandler(errMsg, REPO_GTEST_DBADDRESS, 0001,
		1,
		REPO_GTEST_AUTH_DATABASE,
		REPO_GTEST_DBUSER, REPO_GTEST_DBPW);
	EXPECT_FALSE(wrongPort);
	

	//Check can connect without authentication
	MongoDatabaseHandler *noauth = MongoDatabaseHandler::getHandler(errMsg, REPO_GTEST_DBADDRESS, REPO_GTEST_DBPORT,
		1);

	EXPECT_TRUE(noauth);
	MongoDatabaseHandler::disconnectHandler();
}

TEST(MongoDatabaseHandlerTest, CreateBSONCredentials)
{
	auto handler = getHandler();
	ASSERT_TRUE(handler);
	EXPECT_TRUE(handler->createBSONCredentials("testdb" , "username", "password"));
	EXPECT_TRUE(handler->createBSONCredentials("testdb" , "username", "password", true));
	EXPECT_FALSE(handler->createBSONCredentials(""      , "username", "password"));
	EXPECT_FALSE(handler->createBSONCredentials("testdb", ""        , "password"));
	EXPECT_FALSE(handler->createBSONCredentials("testdb", "username", ""));
}

TEST(MongoDatabaseHandlerTest, CountItemsInCollection)
{
	auto handler = getHandler();
	ASSERT_TRUE(handler);	
	auto goldenData = getCollectionCounts(REPO_GTEST_DBNAME1);
	for (const auto &pair : goldenData)
	{
		std::string message;
		EXPECT_EQ(pair.second, handler->countItemsInCollection(REPO_GTEST_DBNAME1, pair.first, message)); 
		EXPECT_TRUE(message.empty());
	}

	goldenData = getCollectionCounts(REPO_GTEST_DBNAME2);
	for (const auto &pair : goldenData)
	{
		std::string message;
		EXPECT_EQ(pair.second, handler->countItemsInCollection(REPO_GTEST_DBNAME2, pair.first, message));
		EXPECT_TRUE(message.empty());
	}

	std::string message;
	EXPECT_EQ(0, handler->countItemsInCollection("", "", message));
	EXPECT_FALSE(message.empty());

	message.clear();
	EXPECT_EQ(0, handler->countItemsInCollection("", "blah", message));
	EXPECT_FALSE(message.empty());

	message.clear();
	EXPECT_EQ(0, handler->countItemsInCollection("blah", "", message));
	EXPECT_FALSE(message.empty());

	message.clear();
	EXPECT_EQ(0, handler->countItemsInCollection("blah", "blah", message));
	EXPECT_TRUE(message.empty());

}

TEST(MongoDatabaseHandlerTest, GetAllFromCollectionTailable)
{
	auto handler = getHandler();
	ASSERT_TRUE(handler);
	auto goldenData = getGoldenForGetAllFromCollectionTailable();


	std::vector<repo::core::model::RepoBSON> bsons = handler->getAllFromCollectionTailable(
		goldenData.first.first, goldenData.first.second);

	ASSERT_EQ(bsons.size(), goldenData.second.size());
	/*auto goldenDataDisposable = goldenData.second;
	for (int i = 0; i < bsons.size(); ++i)
	{
		bool foundMatch = false;
		for (int j = 0; j< goldenDataDisposable.size(); ++j)
		{
			if (foundMatch = bsons[i].toString() == goldenDataDisposable[j])
			{
				goldenDataDisposable.erase(goldenDataDisposable.begin() + j);
				break;
			}
				
		}
		EXPECT_TRUE(foundMatch);
		
	}*/

	//Test limit and skip
	std::vector<repo::core::model::RepoBSON> bsonsLimitSkip = handler->getAllFromCollectionTailable(
		goldenData.first.first, goldenData.first.second, 1, 1);

	ASSERT_EQ(bsonsLimitSkip.size(), 1);

	//EXPECT_EQ(bsonsLimitSkip[0].toString(), goldenData.second[1]);

	//test projection
	auto bsonsProjected = handler->getAllFromCollectionTailable(<commit_msg>#13 test limit and skip content<commit_after>/**
*  Copyright (C) 2015 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 of the
*  License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <gtest/gtest.h>
#include <repo/core/handler/repo_database_handler_mongo.h>
#include "../../../repo_test_database_info.h"

using namespace repo::core::handler;

MongoDatabaseHandler* getHandler()
{
	std::string errMsg;
	return 	MongoDatabaseHandler::getHandler(errMsg, REPO_GTEST_DBADDRESS, REPO_GTEST_DBPORT,
		1,
		REPO_GTEST_AUTH_DATABASE,
		REPO_GTEST_DBUSER, REPO_GTEST_DBPW);
}

TEST(MongoDatabaseHandlerTest, GetHandlerDisconnectHandler)
{

	std::string errMsg;
	MongoDatabaseHandler* handler =
		MongoDatabaseHandler::getHandler(errMsg, REPO_GTEST_DBADDRESS, REPO_GTEST_DBPORT,
		1,
		REPO_GTEST_AUTH_DATABASE, 
		REPO_GTEST_DBUSER, REPO_GTEST_DBPW);

	EXPECT_TRUE(handler);
	EXPECT_TRUE(errMsg.empty());

	EXPECT_TRUE(MongoDatabaseHandler::getHandler(REPO_GTEST_DBADDRESS));
	MongoDatabaseHandler::disconnectHandler();

	EXPECT_FALSE(MongoDatabaseHandler::getHandler(REPO_GTEST_DBADDRESS));

	MongoDatabaseHandler *wrongAdd = MongoDatabaseHandler::getHandler(errMsg, "blah", REPO_GTEST_DBPORT,
		1,
		REPO_GTEST_AUTH_DATABASE,
		REPO_GTEST_DBUSER, REPO_GTEST_DBPW);

	EXPECT_FALSE(wrongAdd);
	MongoDatabaseHandler *wrongPort = MongoDatabaseHandler::getHandler(errMsg, REPO_GTEST_DBADDRESS, 0001,
		1,
		REPO_GTEST_AUTH_DATABASE,
		REPO_GTEST_DBUSER, REPO_GTEST_DBPW);
	EXPECT_FALSE(wrongPort);
	

	//Check can connect without authentication
	MongoDatabaseHandler *noauth = MongoDatabaseHandler::getHandler(errMsg, REPO_GTEST_DBADDRESS, REPO_GTEST_DBPORT,
		1);

	EXPECT_TRUE(noauth);
	MongoDatabaseHandler::disconnectHandler();
}

TEST(MongoDatabaseHandlerTest, CreateBSONCredentials)
{
	auto handler = getHandler();
	ASSERT_TRUE(handler);
	EXPECT_TRUE(handler->createBSONCredentials("testdb" , "username", "password"));
	EXPECT_TRUE(handler->createBSONCredentials("testdb" , "username", "password", true));
	EXPECT_FALSE(handler->createBSONCredentials(""      , "username", "password"));
	EXPECT_FALSE(handler->createBSONCredentials("testdb", ""        , "password"));
	EXPECT_FALSE(handler->createBSONCredentials("testdb", "username", ""));
}

TEST(MongoDatabaseHandlerTest, CountItemsInCollection)
{
	auto handler = getHandler();
	ASSERT_TRUE(handler);	
	auto goldenData = getCollectionCounts(REPO_GTEST_DBNAME1);
	for (const auto &pair : goldenData)
	{
		std::string message;
		EXPECT_EQ(pair.second, handler->countItemsInCollection(REPO_GTEST_DBNAME1, pair.first, message)); 
		EXPECT_TRUE(message.empty());
	}

	goldenData = getCollectionCounts(REPO_GTEST_DBNAME2);
	for (const auto &pair : goldenData)
	{
		std::string message;
		EXPECT_EQ(pair.second, handler->countItemsInCollection(REPO_GTEST_DBNAME2, pair.first, message));
		EXPECT_TRUE(message.empty());
	}

	std::string message;
	EXPECT_EQ(0, handler->countItemsInCollection("", "", message));
	EXPECT_FALSE(message.empty());

	message.clear();
	EXPECT_EQ(0, handler->countItemsInCollection("", "blah", message));
	EXPECT_FALSE(message.empty());

	message.clear();
	EXPECT_EQ(0, handler->countItemsInCollection("blah", "", message));
	EXPECT_FALSE(message.empty());

	message.clear();
	EXPECT_EQ(0, handler->countItemsInCollection("blah", "blah", message));
	EXPECT_TRUE(message.empty());

}

TEST(MongoDatabaseHandlerTest, GetAllFromCollectionTailable)
{
	auto handler = getHandler();
	ASSERT_TRUE(handler);
	auto goldenData = getGoldenForGetAllFromCollectionTailable();

	std::vector<repo::core::model::RepoBSON> bsons = handler->getAllFromCollectionTailable(
		goldenData.first.first, goldenData.first.second);

	ASSERT_EQ(bsons.size(), goldenData.second.size());
	/*auto goldenDataDisposable = goldenData.second;
	for (int i = 0; i < bsons.size(); ++i)
	{
		bool foundMatch = false;
		for (int j = 0; j< goldenDataDisposable.size(); ++j)
		{
			if (foundMatch = bsons[i].toString() == goldenDataDisposable[j])
			{
				goldenDataDisposable.erase(goldenDataDisposable.begin() + j);
				break;
			}
				
		}
		EXPECT_TRUE(foundMatch);
		
	}*/

	//Test limit and skip
	std::vector<repo::core::model::RepoBSON> bsonsLimitSkip = handler->getAllFromCollectionTailable(
		goldenData.first.first, goldenData.first.second, 1, 1);

	ASSERT_EQ(bsonsLimitSkip.size(), 1);

	EXPECT_EQ(bsonsLimitSkip[0].toString(), bsons[1]);

	//test projection
	auto bsonsProjected = handler->getAllFromCollectionTailable(
{'fraction_non_alphanumeric': 0.12222995130676736, 'fraction_numerical': 0.00616118453741429, 'mean_word_length': 6.454814814814815, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3956578', 'n_tokens_mistral': 3497, 'n_tokens_neox': 3376, 'n_words': 650}