Skip to content
This repository has been archived by the owner on Nov 8, 2024. It is now read-only.

[DX-378] Fix handling of None by VerifyAccount #18

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions libs/EnjinPlatformSdk/include/EnjinPlatformSdk/IGraphQlRequest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ class IGraphQlRequest : virtual public IGraphQlUploadHolder
[[nodiscard]]
virtual const std::map<std::string, SerializablePtr>& GetVariablesWithoutTypes() const = 0;

/// \brief Determines whether this request has a variable of the given name.
/// \param name The variable name.
/// \return Whether this request has the variable.
[[maybe_unused]]
[[nodiscard]]
virtual bool HasVariable(const std::string& name) const = 0;

/// \brief Determines whether this request has variables.
/// \return Whether this request has variables.
[[maybe_unused]]
Expand All @@ -64,6 +71,12 @@ class IGraphQlRequest<TRequest> : virtual public IGraphQlRequest<>
/// \return This request for chaining.
[[maybe_unused]]
virtual TRequest& SetVariable(std::string name, std::string type, SerializablePtr value) = 0;

/// \brief Removes a variable with the given name from this request.
/// \param name The variable name.
/// \return This request for chaining.
[[maybe_unused]]
virtual TRequest& RemoveVariable(const std::string& name) = 0;
};

/// \brief Interface for GraphQL requests with a settable fragment for response data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,21 @@ class GraphQlRequestBase : public GraphQlParameterHolder<TRequest>,
return _variablesWithoutTypes;
}

[[maybe_unused]]
[[nodiscard]]
bool HasVariable(const std::string& name) const override
{
return _variables.contains(name);
}

[[maybe_unused]]
[[nodiscard]]
bool HasVariables() const override
{
return !_variables.empty();
}

[[maybe_unused]]
TRequest& SetVariable(std::string name, std::string type, SerializablePtr value) override
{
if (value == nullptr)
Expand All @@ -91,13 +99,26 @@ class GraphQlRequestBase : public GraphQlParameterHolder<TRequest>,
return static_cast<TRequest&>(*this);
}

[[maybe_unused]]
TRequest& RemoveVariable(const std::string& name) override
{
if (_variables.contains(name))
{
_variables.erase(name);
_variablesWithoutTypes.erase(name);
}

return static_cast<TRequest&>(*this);
}

// endregion IGraphQlRequest

protected:
/// \brief Base constructor to be used by GraphQL requests.
/// \param name The name of the request.
/// \param type The type of the request.
/// \throws std::out_of_range If request type is not a valid value.
[[maybe_unused]]
GraphQlRequestBase(std::string name, GraphQlRequestType type)
: _name(std::move(name)),
_type(type)
Expand All @@ -122,6 +143,7 @@ class GraphQlRequestBase : public GraphQlParameterHolder<TRequest>,
/// \brief Appends the necessary beginning portion for the compiled request to the given string stream, leaving only
/// the closing brace and any fragment fields to be appended.
/// \param ss The string stream to write to.
[[maybe_unused]]
void AppendHeader(std::stringstream& ss) const
{
ss << _typeName;
Expand Down
9 changes: 8 additions & 1 deletion libs/EnjinPlatformSdk/src/schema/mutations/VerifyAccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,17 @@ VerifyAccount& VerifyAccount::SetAccount(SerializableStringPtr account)
[[maybe_unused]]
VerifyAccount& VerifyAccount::SetCryptoSignatureType(const CryptoSignatureType cryptoSignatureType)
{
constexpr char name[] = "cryptoSignatureType";

if (cryptoSignatureType == CryptoSignatureType::None)
{
return RequestType::RemoveVariable(name);
}

std::string s = enjin::platform::sdk::ToString(cryptoSignatureType);
SerializableStringPtr sPtr = std::make_shared<SerializableString>(std::move(s));

return RequestType::SetVariable("cryptoSignatureType", CoreTypes::CryptoSignatureType, std::move(sPtr));
return RequestType::SetVariable(name, CoreTypes::CryptoSignatureType, std::move(sPtr));
}

VerifyAccount& VerifyAccount::operator=(const VerifyAccount& rhs) = default;
Expand Down
58 changes: 58 additions & 0 deletions tests/unit/graphql/GraphQlRequestBaseTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,31 @@ TEST_F(GraphQlRequestBaseTest, GetVariablesWithoutTypesWhenRequestHasVariablesRe
ASSERT_THAT(actual, Eq(expected));
}

TEST_F(GraphQlRequestBaseTest, HasVariableWhenRequestDoesNotHaveTheGivenVariableReturnsFalse)
{
// Arrange
const std::string name("var");

// Act
const bool actual = classUnderTest->HasVariable(name);

// Assert
ASSERT_THAT(actual, IsFalse());
}

TEST_F(GraphQlRequestBaseTest, HasVariableWhenRequestHasTheGivenVariableReturnsTrue)
{
// Arrange
const std::string name("var");
classUnderTest->SetVariable(name, "String!", mockVariableValue);

// Act
const bool actual = classUnderTest->HasVariable(name);

// Assert
ASSERT_THAT(actual, IsTrue());
}

TEST_F(GraphQlRequestBaseTest, HasVariablesWhenRequestHasNoVariablesReturnsFalse)
{
// Act
Expand All @@ -169,3 +194,36 @@ TEST_F(GraphQlRequestBaseTest, HasVariablesWhenRequestHasVariablesReturnsTrue)
// Assert
ASSERT_TRUE(actual);
}

TEST_F(GraphQlRequestBaseTest, SetVariableVariableIsSetForRequest)
{
// Arrange
const std::string name("var");
const std::string type("type");
const std::shared_ptr<ISerializable> value = mockVariableValue;

// Act
classUnderTest->SetVariable(name, type, value);

// Assert
ASSERT_THAT(classUnderTest->GetVariablesWithoutTypes(), Contains(Key(name)));
ASSERT_THAT(classUnderTest->GetVariablesWithoutTypes().find(name)->second, Eq(value));
}

TEST_F(GraphQlRequestBaseTest, RemoveVariableWhenVariableIsSetRemovesVariable)
{
// Arrange
const std::string name("var");
classUnderTest->SetVariable(name, "type", mockVariableValue);

// Assumptions
ASSERT_THAT(classUnderTest->GetVariablesWithoutTypes(), Contains(Key(name)))
<< "Assume that variable is set";

// Act
classUnderTest->RemoveVariable(name);

// Assert
ASSERT_THAT(classUnderTest->GetVariablesWithoutTypes(), Not(Contains(Key(name))))
<< "Assume that variable was removed";
}
1 change: 1 addition & 0 deletions tests/unit/schema/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
add_subdirectory(mutations)
add_subdirectory(queries)
3 changes: 3 additions & 0 deletions tests/unit/schema/mutations/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target_sources(${TESTS_NAME}
PRIVATE
VerifyAccountTest.cpp)
101 changes: 101 additions & 0 deletions tests/unit/schema/mutations/VerifyAccountTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "EnjinPlatformSdk/CryptoSignatureType.hpp"
#include "EnjinPlatformSdk/VerifyAccount.hpp"
#include <memory>

using namespace enjin::platform::sdk;
using namespace testing;

class VerifyAccountTestSuite
{
public:
static inline const std::string CryptoSignatureTypeName = "cryptoSignatureType";
};

class VerifyAccountTest : public Test,
public VerifyAccountTestSuite
{
public:
std::unique_ptr<VerifyAccount> classUnderTest;

protected:
void SetUp() override
{
Test::SetUp();

classUnderTest = std::make_unique<VerifyAccount>();
}
};

class VerifyAccountCryptoSignatureTypeTest : public TestWithParam<CryptoSignatureType>,
public VerifyAccountTestSuite
{
public:
std::unique_ptr<VerifyAccount> classUnderTest;

protected:
void SetUp() override
{
TestWithParam<CryptoSignatureType>::SetUp();

classUnderTest = std::make_unique<VerifyAccount>();
}
};

TEST_F(VerifyAccountTest, SetCryptoSignatureTypeWhenVariableIsNotSetAndGivenNoneDoesNotSetTheVariable)
{
// Arrange
const CryptoSignatureType cryptoSignatureType = CryptoSignatureType::None;

// Assumptions
ASSERT_THAT(classUnderTest->HasVariable(CryptoSignatureTypeName), IsFalse())
<< "Assume that the '" << CryptoSignatureTypeName << "' variable is not set";

// Act
classUnderTest->SetCryptoSignatureType(cryptoSignatureType);

// Assert
ASSERT_THAT(classUnderTest->HasVariable(CryptoSignatureTypeName), IsFalse())
<< "Assert that the '" << CryptoSignatureTypeName << "' variable was not set";
}

TEST_F(VerifyAccountTest, SetCryptoSignatureTypeWhenVariableIsSetAndGivenNoneRemovesTheVariable)
{
// Arrange
const CryptoSignatureType cryptoSignatureType = CryptoSignatureType::None;
classUnderTest->SetCryptoSignatureType(CryptoSignatureType::Ed25519);

// Assumptions
ASSERT_THAT(classUnderTest->HasVariable(CryptoSignatureTypeName), IsTrue())
<< "Assume that the '" << CryptoSignatureTypeName << "' variable is set";

// Act
classUnderTest->SetCryptoSignatureType(cryptoSignatureType);

// Assert
ASSERT_THAT(classUnderTest->HasVariable(CryptoSignatureTypeName), IsFalse())
<< "Assert that the '" << CryptoSignatureTypeName << "' variable was removed";
}

TEST_P(VerifyAccountCryptoSignatureTypeTest, SetCryptoSignatureTypeWhenGivenNonNoneTypeVariableIsSet)
{
// Arrange
const CryptoSignatureType cryptoSignatureType = GetParam();

// Assumptions
ASSERT_THAT(classUnderTest->HasVariable(CryptoSignatureTypeName), IsFalse())
<< "Assume that the '" << CryptoSignatureTypeName << "' variable is not set";

// Act
classUnderTest->SetCryptoSignatureType(cryptoSignatureType);

// Assert
ASSERT_THAT(classUnderTest->HasVariable(CryptoSignatureTypeName), IsTrue())
<< "Assert that the '" << CryptoSignatureTypeName << "' variable was set";
}

INSTANTIATE_TEST_SUITE_P(NonNoneCryptoSignatureType,
VerifyAccountCryptoSignatureTypeTest,
Values(CryptoSignatureType::Ed25519,
CryptoSignatureType::Sr25519));