| #include "remote_credentials.h" |
| |
| #include <array> |
| |
| #include "gmock.h" |
| #include "gunit.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| |
| namespace milotic { |
| namespace { |
| |
| using ::testing::_; |
| using ::testing::Field; |
| using ::testing::InSequence; |
| using ::testing::MockFunction; |
| using ::testing::Return; |
| using ::testing::StrictMock; |
| using ::testing::status::IsOkAndHolds; |
| using ::testing::status::StatusIs; |
| |
| struct TestManager { |
| public: |
| TestManager() |
| : reader(mock_reader.AsStdFunction()), |
| writer(mock_writer.AsStdFunction()), |
| manager(reader, writer) {} |
| |
| StrictMock<MockFunction<CredentialsFileReader>> mock_reader; |
| StrictMock<MockFunction<CredentialsFileWriter>> mock_writer; |
| |
| private: |
| CredentialsFileReader reader; |
| CredentialsFileWriter writer; |
| |
| public: |
| CredentialsFileManager manager; |
| }; |
| |
| TEST(CredentialsFileManagerTest, FilesAreTriedInSequenceOnReadError) { |
| TestManager test_manager; |
| auto source_files = std::to_array({"file1", "file2"}); |
| test_manager.manager.AddSourceFiles(source_files.begin(), source_files.end()); |
| test_manager.manager.SetPrivateCachePath("cache/file"); |
| |
| InSequence seq; |
| EXPECT_CALL(test_manager.mock_reader, Call("cache/file", "endpoint")) |
| .WillOnce(Return(absl::InternalError("test error1"))); |
| EXPECT_CALL(test_manager.mock_reader, Call("file1", "endpoint")) |
| .WillOnce(Return(absl::InternalError("test error2"))); |
| EXPECT_CALL(test_manager.mock_reader, Call("file2", "endpoint")) |
| .WillOnce(Return(absl::InternalError("test error3"))); |
| |
| EXPECT_THAT(test_manager.manager.RunLogin( |
| "endpoint", |
| [](const absl::StatusOr<RemoteCredentials>& c) { |
| return c.status(); |
| }), |
| StatusIs(absl::StatusCode::kInternal, "test error3")); |
| } |
| |
| TEST(CredentialsFileManagerTest, FilesAreTriedInSequenceOnLoginError) { |
| TestManager test_manager; |
| auto source_files = std::to_array({"file1", "file2"}); |
| test_manager.manager.AddSourceFiles(source_files.begin(), source_files.end()); |
| test_manager.manager.SetPrivateCachePath("cache/file"); |
| |
| MockFunction<LoginFunction> mock_login_function; |
| |
| InSequence seq; |
| EXPECT_CALL(test_manager.mock_reader, Call("cache/file", "endpoint")) |
| .WillOnce(Return(RemoteCredentials{.password = "test_password1"})); |
| EXPECT_CALL(mock_login_function, |
| Call(IsOkAndHolds(Field("password", &RemoteCredentials::password, |
| "test_password1")))) |
| .WillOnce(Return(absl::UnauthenticatedError("test error1"))); |
| |
| EXPECT_CALL(test_manager.mock_reader, Call("file1", "endpoint")) |
| .WillOnce(Return(RemoteCredentials{.password = "test_password2"})); |
| EXPECT_CALL(mock_login_function, |
| Call(IsOkAndHolds(Field("password", &RemoteCredentials::password, |
| "test_password2")))) |
| .WillOnce(Return(absl::UnauthenticatedError("test error2"))); |
| |
| EXPECT_CALL(test_manager.mock_reader, Call("file2", "endpoint")) |
| .WillOnce(Return(RemoteCredentials{.password = "test_password3"})); |
| EXPECT_CALL(mock_login_function, |
| Call(IsOkAndHolds(Field("password", &RemoteCredentials::password, |
| "test_password3")))) |
| .WillOnce(Return(absl::UnauthenticatedError("test error3"))); |
| |
| EXPECT_THAT(test_manager.manager.RunLogin( |
| "endpoint", mock_login_function.AsStdFunction()), |
| StatusIs(absl::StatusCode::kUnauthenticated, "test error3")); |
| } |
| |
| TEST(CredentialsFileManagerTest, FirstSuccessIsUsed) { |
| TestManager test_manager; |
| auto source_files = std::to_array({"file1", "file2", "file3"}); |
| test_manager.manager.AddSourceFiles(source_files.begin(), source_files.end()); |
| |
| EXPECT_CALL(test_manager.mock_reader, Call("file1", _)) |
| .WillOnce(Return(absl::InternalError("test error1"))); |
| EXPECT_CALL(test_manager.mock_reader, Call("file2", _)) |
| .WillOnce(Return(RemoteCredentials{.password = "test_password"})); |
| EXPECT_CALL(test_manager.mock_reader, Call("file3", _)).Times(0); |
| |
| MockFunction<LoginFunction> mock_login_function; |
| EXPECT_CALL(mock_login_function, |
| Call(IsOkAndHolds(Field("password", &RemoteCredentials::password, |
| "test_password")))) |
| .WillOnce(Return(absl::OkStatus())); |
| EXPECT_OK(test_manager.manager.RunLogin("endpoint", |
| mock_login_function.AsStdFunction())); |
| } |
| |
| TEST(CredentialsFileManagerTest, WorkingCredentialsAreCached) { |
| TestManager test_manager; |
| auto source_files = std::to_array({"file1"}); |
| test_manager.manager.AddSourceFiles(source_files.begin(), source_files.end()); |
| test_manager.manager.SetPrivateCachePath("cache/file"); |
| |
| EXPECT_CALL(test_manager.mock_reader, Call("cache/file", _)) |
| .WillOnce(Return(absl::NotFoundError("no cache"))); |
| EXPECT_CALL(test_manager.mock_reader, Call("file1", _)) |
| .WillOnce(Return(RemoteCredentials{.password = "test_password"})); |
| |
| EXPECT_CALL( |
| test_manager.mock_writer, |
| Call("cache/file", "file1", |
| Field("password", &RemoteCredentials::password, "test_password"), _)) |
| .WillOnce(Return(absl::OkStatus())); |
| |
| MockFunction<LoginFunction> mock_login_function; |
| EXPECT_CALL(mock_login_function, |
| Call(IsOkAndHolds(Field("password", &RemoteCredentials::password, |
| "test_password")))) |
| .WillOnce(Return(absl::OkStatus())); |
| EXPECT_OK(test_manager.manager.RunLogin("endpoint", |
| mock_login_function.AsStdFunction())); |
| } |
| |
| TEST(CredentialsFileManagerTest, CachedCredentialsAreNotRewritten) { |
| TestManager test_manager; |
| auto source_files = std::to_array({"file1"}); |
| test_manager.manager.AddSourceFiles(source_files.begin(), source_files.end()); |
| test_manager.manager.SetPrivateCachePath("cache/file"); |
| |
| EXPECT_CALL(test_manager.mock_reader, Call("cache/file", _)) |
| .WillOnce(Return(RemoteCredentials{.password = "test_password"})); |
| EXPECT_CALL(test_manager.mock_reader, Call("file1", _)).Times(0); |
| EXPECT_CALL(test_manager.mock_writer, Call).Times(0); |
| |
| MockFunction<LoginFunction> mock_login_function; |
| EXPECT_CALL(mock_login_function, |
| Call(IsOkAndHolds(Field("password", &RemoteCredentials::password, |
| "test_password")))) |
| .WillOnce(Return(absl::OkStatus())); |
| EXPECT_OK(test_manager.manager.RunLogin("endpoint", |
| mock_login_function.AsStdFunction())); |
| } |
| |
| TEST(CredentialsFileManagerTest, WorkingCredentialsAreReadOnce) { |
| TestManager test_manager; |
| auto source_files = std::to_array({"file1"}); |
| test_manager.manager.AddSourceFiles(source_files.begin(), source_files.end()); |
| test_manager.manager.SetPrivateCachePath("cache/file"); |
| |
| EXPECT_CALL(test_manager.mock_reader, Call("cache/file", _)) |
| .WillOnce(Return(RemoteCredentials{.password = "test_password"})); |
| |
| MockFunction<LoginFunction> mock_login_function; |
| EXPECT_CALL(mock_login_function, |
| Call(IsOkAndHolds(Field("password", &RemoteCredentials::password, |
| "test_password")))) |
| .Times(2) |
| .WillRepeatedly(Return(absl::OkStatus())); |
| EXPECT_OK(test_manager.manager.RunLogin("endpoint", |
| mock_login_function.AsStdFunction())); |
| EXPECT_OK(test_manager.manager.RunLogin("endpoint", |
| mock_login_function.AsStdFunction())); |
| } |
| |
| TEST(CredentialsFileManagerTest, CredentialsAreRefreshedIfTheyStopWorking) { |
| TestManager test_manager; |
| auto source_files = std::to_array({"file1", "file2"}); |
| test_manager.manager.AddSourceFiles(source_files.begin(), source_files.end()); |
| test_manager.manager.SetPrivateCachePath("cache/file"); |
| |
| EXPECT_CALL(test_manager.mock_reader, Call("cache/file", _)) |
| .WillOnce(Return(absl::NotFoundError("no cache"))); |
| EXPECT_CALL(test_manager.mock_reader, Call("file1", _)) |
| .Times(2) |
| .WillRepeatedly(Return(RemoteCredentials{.password = "test_password1"})); |
| EXPECT_CALL(test_manager.mock_reader, Call("file2", _)) |
| .WillOnce(Return(RemoteCredentials{.password = "test_password2"})); |
| |
| EXPECT_CALL( |
| test_manager.mock_writer, |
| Call("cache/file", "file1", |
| Field("password", &RemoteCredentials::password, "test_password1"), |
| _)) |
| .WillOnce(Return(absl::OkStatus())); |
| EXPECT_CALL( |
| test_manager.mock_writer, |
| Call("cache/file", "file2", |
| Field("password", &RemoteCredentials::password, "test_password2"), |
| _)) |
| .WillOnce(Return(absl::OkStatus())); |
| |
| MockFunction<LoginFunction> mock_login_function; |
| EXPECT_CALL(mock_login_function, |
| Call(IsOkAndHolds(Field("password", &RemoteCredentials::password, |
| "test_password1")))) |
| .WillOnce(Return(absl::OkStatus())) |
| .WillRepeatedly(Return(absl::UnauthenticatedError("test error1"))); |
| EXPECT_CALL(mock_login_function, |
| Call(IsOkAndHolds(Field("password", &RemoteCredentials::password, |
| "test_password2")))) |
| .WillOnce(Return(absl::OkStatus())); |
| |
| EXPECT_OK(test_manager.manager.RunLogin("endpoint", |
| mock_login_function.AsStdFunction())); |
| EXPECT_OK(test_manager.manager.RunLogin("endpoint", |
| mock_login_function.AsStdFunction())); |
| } |
| |
| } // namespace |
| } // namespace milotic |