Skip to content
Open
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
98 changes: 81 additions & 17 deletions tests/lib/ocpp/v2/functional_blocks/test_authorization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,20 +346,30 @@ TEST_F(AuthorizationTest, is_auth_cache_ctrlr_enabled) {
this->authorization = std::make_unique<Authorization>(context);
EXPECT_FALSE(authorization->is_auth_cache_ctrlr_enabled());
}

TEST_F(AuthorizationTest, authorize_req_websocket_disconnected) {
// Try to do an authorize request when the websocket is disconnected.
// Test: Authorize request should return Unknown when WebSocket is offline
// Setup: Explicitly disable all local authorization options
this->set_local_pre_authorize(this->device_model, false);
this->set_local_authorize_offline(this->device_model, false);

// Simulate offline WebSocket connection
ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(false));

const AuthorizeResponse response = authorization->authorize_req(get_id_token(), std::nullopt, std::nullopt);
EXPECT_EQ(response.idTokenInfo.status, AuthorizationStatusEnum::Unknown);
}

TEST_F(AuthorizationTest, authorize_req_wrong_future_message_type) {
// Try to do an authorize request with the websocket connected. The dispatch_call_async returns
// a wrong message type.
// Test: Response should be Unknown if dispatch_call_async returns wrong message type
// Setup: Disable local auth and simulate online WebSocket
this->set_local_pre_authorize(this->device_model, false);
this->set_local_authorize_offline(this->device_model, false);

ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true));

ocpp::EnhancedMessage<MessageType> enhanced_message;
enhanced_message.messageType = MessageType::GetDisplayMessages;

EXPECT_CALL(mock_dispatcher, dispatch_call_async(_, _))
.WillOnce(Return(std::async(std::launch::deferred, [enhanced_message]() { return enhanced_message; })));

Expand All @@ -368,8 +378,13 @@ TEST_F(AuthorizationTest, authorize_req_wrong_future_message_type) {
}

TEST_F(AuthorizationTest, authorize_req_accepted) {
// Try to do an authorize request, which is accepted.
// Test: Authorize request returns Accepted when WebSocket is online and dispatcher responds positively
// Setup: Disable local auth, simulate online WebSocket, and mock Accepted response
this->set_local_pre_authorize(this->device_model, false);
this->set_local_authorize_offline(this->device_model, false);

ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true));

EXPECT_CALL(mock_dispatcher, dispatch_call_async(_, _)).WillOnce(Return(std::async(std::launch::deferred, [this]() {
return create_example_authorize_response(AuthorizeCertificateStatusEnum::Accepted,
AuthorizationStatusEnum::Accepted);
Expand All @@ -380,26 +395,36 @@ TEST_F(AuthorizationTest, authorize_req_accepted) {
}

TEST_F(AuthorizationTest, authorize_req_exception) {
// Try to do an authorize request, during which which an exception is thrown.
// Test: An exception in AuthorizationStatusEnum deserialization leads to Unknown response
// Setup: Disable local auth, simulate online WebSocket, and mock invalid status value
this->set_local_pre_authorize(this->device_model, false);
this->set_local_authorize_offline(this->device_model, false);

ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true));

EXPECT_CALL(mock_dispatcher, dispatch_call_async(_, _)).WillOnce(Return(std::async(std::launch::deferred, [this]() {
// Create authorize response with a wrong enum value, which will throw.
return create_example_authorize_response(AuthorizeCertificateStatusEnum::Accepted,
static_cast<AuthorizationStatusEnum>(INT32_MAX));
return create_example_authorize_response(
AuthorizeCertificateStatusEnum::Accepted,
static_cast<AuthorizationStatusEnum>(INT32_MAX) // invalid value triggers exception
);
})));

const AuthorizeResponse response = authorization->authorize_req(get_id_token(), std::nullopt, std::nullopt);
EXPECT_EQ(response.idTokenInfo.status, AuthorizationStatusEnum::Unknown);
}

TEST_F(AuthorizationTest, authorize_req_exception2) {
// Try to do an authorization request, an exception is thrown for the authorize response.
// Test: An exception in AuthorizeCertificateStatusEnum deserialization leads to Unknown response
// Setup: Disable local auth, simulate online WebSocket, and mock invalid certificate status
this->set_local_pre_authorize(this->device_model, false);
this->set_local_authorize_offline(this->device_model, false);

ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true));

EXPECT_CALL(mock_dispatcher, dispatch_call_async(_, _)).WillOnce(Return(std::async(std::launch::deferred, [this]() {
// Create authorize response with a from enum value for the authorize certificute status, which will
// cause an exception to be thrown.
return create_example_authorize_response(static_cast<AuthorizeCertificateStatusEnum>(INT32_MAX),
AuthorizationStatusEnum::Accepted);
return create_example_authorize_response(
static_cast<AuthorizeCertificateStatusEnum>(INT32_MAX), // invalid cert status
AuthorizationStatusEnum::Accepted);
})));

const AuthorizeResponse response = authorization->authorize_req(get_id_token(), std::nullopt, std::nullopt);
Expand Down Expand Up @@ -517,6 +542,11 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_accepted) {
// Local auth list is enabled.
this->set_local_auth_list_ctrlr_enabled(this->device_model, true);

// Explicit config setup for test isolation
set_local_pre_authorize(this->device_model, false);
set_local_authorize_offline(this->device_model, false);
ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true));

IdTokenInfo id_token_info_result;
id_token_info_result.status = AuthorizationStatusEnum::Accepted;

Expand All @@ -540,6 +570,11 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_unknown_no_remo
// Disable remote authorization.
this->disable_remote_authorization(this->device_model, true);

// Explicit config setup for test isolation
set_local_pre_authorize(this->device_model, false);
set_local_authorize_offline(this->device_model, false);
ON_CALL(this->connectivity_manager, is_websocket_connected()).WillByDefault(Return(true));

IdTokenInfo id_token_info_result;
id_token_info_result.status = AuthorizationStatusEnum::Invalid;

Expand All @@ -555,14 +590,19 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_unknown_no_remo
}

TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_unknown_websocket_disconnected) {
// Validate token with the local auth list: unknown the websocket is not connected and token info
// Validate token with the local auth list: unknown because the websocket is not connected and token info
// status is not accepted. Set AuthCtrlr::Enabled to true
this->set_auth_ctrlr_enabled(this->device_model, true);
// Local auth list is enabled.
this->set_local_auth_list_ctrlr_enabled(this->device_model, true);
// Remote authorization is enabled.
this->disable_remote_authorization(this->device_model, false);
// But the websocket is disconnected so it is not possible to authorize the request.

// Explicit config setup for test isolation
set_local_pre_authorize(this->device_model, false);
set_local_authorize_offline(this->device_model, false);

// WebSocket is disconnected for this test case
EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(false));

IdTokenInfo id_token_info_result;
Expand All @@ -587,7 +627,12 @@ TEST_F(AuthorizationTest, validate_token_local_auth_list_enabled_connectivity_ma
this->set_local_auth_list_ctrlr_enabled(this->device_model, true);
// Remote authorization is enabled.
this->disable_remote_authorization(this->device_model, false);
// But the websocket is connected so it is possible to authorize the request.

// Explicit config setup for test isolation
set_local_pre_authorize(this->device_model, false);
set_local_authorize_offline(this->device_model, false);

// WebSocket is connected
EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(true));
// Authorize request returns 'Accepted'.
EXPECT_CALL(mock_dispatcher, dispatch_call_async(_, _)).WillOnce(Return(std::async(std::launch::deferred, [this]() {
Expand Down Expand Up @@ -658,7 +703,12 @@ TEST_F(
// And offline contract validation is not allowed.
this->set_allow_contract_validation_offline(this->device_model, true);
this->set_local_authorize_offline(this->device_model, false);

// Explicit config setup for test isolation
set_local_pre_authorize(this->device_model, false);

ON_CALL(this->evse_security, verify_certificate(_, DEFAULT_LEAF_CERT_TYPE))

.WillByDefault(Return(ocpp::CertificateValidationResult::Valid));

IdToken id_token;
Expand All @@ -681,7 +731,12 @@ TEST_F(
this->set_allow_contract_validation_offline(this->device_model, true);
this->set_local_authorize_offline(this->device_model, true);
this->set_local_auth_list_ctrlr_enabled(this->device_model, true);

// Explicit config setup for test isolation
set_local_pre_authorize(this->device_model, false);

ON_CALL(this->evse_security, verify_certificate(_, DEFAULT_LEAF_CERT_TYPE))

.WillByDefault(Return(ocpp::CertificateValidationResult::Valid));

IdTokenInfo id_token_info_result;
Expand All @@ -707,6 +762,10 @@ TEST_F(AuthorizationTest,
// And offline contract validation is not allowed.
this->set_allow_contract_validation_offline(this->device_model, true);
this->set_local_authorize_offline(this->device_model, false);

// Explicit config setup for test isolation
set_local_pre_authorize(this->device_model, false);

std::vector<ocpp::LeafCertificateType> types({ocpp::LeafCertificateType::MO, ocpp::LeafCertificateType::V2G});
ON_CALL(this->evse_security, verify_certificate(_, types))
.WillByDefault(Return(ocpp::CertificateValidationResult::Expired));
Expand Down Expand Up @@ -1024,6 +1083,11 @@ TEST_F(AuthorizationTest, validate_token_auth_cache_lifetime_expired) {
this->set_auth_cache_lifetime(this->device_model, 5000);
// Allow remote authorization
this->disable_remote_authorization(this->device_model, false);

// Explicit config setup for test isolation
set_local_pre_authorize(this->device_model, false);
set_local_authorize_offline(this->device_model, false);

// The websocket is connected.
EXPECT_CALL(this->connectivity_manager, is_websocket_connected()).WillRepeatedly(Return(true));

Expand Down
Loading