finger [email protected] (or any mixed-case name) failed because the plan path was built from the raw username while plan files are lower-case on disk. Lower-case the requested name before resolving the plan path; the original spelling is still echoed back when no plan file exists. Add a mock test asserting Pete -> .../pete.
105 lines
3.4 KiB
C++
105 lines
3.4 KiB
C++
#include "handler.hpp"
|
|
#include <filesystem>
|
|
#include <gmock/gmock.h>
|
|
#include <gtest/gtest.h>
|
|
#include <memory>
|
|
|
|
// Mock implementation
|
|
class MockFilesystemWrapper : public IFilesystemWrapper {
|
|
public:
|
|
MOCK_METHOD(bool, exists, (const std::filesystem::path &path),
|
|
(const, override));
|
|
MOCK_METHOD(std::string, read_file, (const std::filesystem::path &path),
|
|
(const, override));
|
|
};
|
|
|
|
// Test fixture for demonstrating Google Mock setup
|
|
class ProcessMockTest : public ::testing::Test {
|
|
protected:
|
|
void SetUp() override {
|
|
mock_filesystem = std::make_unique<MockFilesystemWrapper>();
|
|
}
|
|
|
|
void TearDown() override { mock_filesystem.reset(); }
|
|
|
|
std::unique_ptr<MockFilesystemWrapper> mock_filesystem;
|
|
};
|
|
|
|
// Test using the actual process function with mocked filesystem
|
|
TEST_F(ProcessMockTest, ProcessWithFileExists) {
|
|
// Setup mock expectations
|
|
EXPECT_CALL(*mock_filesystem, exists(::testing::_))
|
|
.WillOnce(::testing::Return(true));
|
|
|
|
EXPECT_CALL(*mock_filesystem, read_file(::testing::_))
|
|
.WillOnce(::testing::Return("Mock file content\r\n"));
|
|
|
|
// Test the actual process function with mocked filesystem
|
|
std::string result = process("testuser", *mock_filesystem);
|
|
EXPECT_EQ(result, "Mock file content\r\n");
|
|
}
|
|
|
|
// Test process function when file doesn't exist
|
|
TEST_F(ProcessMockTest, ProcessWithFileNotFound) {
|
|
EXPECT_CALL(*mock_filesystem, exists(::testing::_))
|
|
.WillOnce(::testing::Return(false));
|
|
|
|
// Test the actual process function - should return username when file doesn't
|
|
// exist
|
|
std::string result = process("nonexistentuser", *mock_filesystem);
|
|
EXPECT_EQ(result, "nonexistentuser");
|
|
}
|
|
|
|
// Test process function when file exists but is empty
|
|
TEST_F(ProcessMockTest, ProcessWithEmptyFile) {
|
|
EXPECT_CALL(*mock_filesystem, exists(::testing::_))
|
|
.WillOnce(::testing::Return(true));
|
|
|
|
EXPECT_CALL(*mock_filesystem, read_file(::testing::_))
|
|
.WillOnce(::testing::Return(""));
|
|
|
|
// Test the actual process function - should return username when file is
|
|
// empty
|
|
std::string result = process("emptyfileuser", *mock_filesystem);
|
|
EXPECT_EQ(result, "emptyfileuser");
|
|
}
|
|
|
|
// Username lookup is case-insensitive: a mixed-case request is lowercased
|
|
// before the plan-file path is built, so "Pete" reads .../pete.
|
|
TEST_F(ProcessMockTest, ProcessLowercasesUsernameForLookup) {
|
|
using ::testing::Return;
|
|
const std::filesystem::path base{"/var/finger/users/"};
|
|
|
|
EXPECT_CALL(*mock_filesystem, exists(base / "pete"))
|
|
.WillOnce(Return(true));
|
|
EXPECT_CALL(*mock_filesystem, read_file(base / "pete"))
|
|
.WillOnce(Return("Just another hacker.\r\n"));
|
|
|
|
std::string result = process("Pete", *mock_filesystem, base);
|
|
EXPECT_EQ(result, "Just another hacker.\r\n");
|
|
}
|
|
|
|
// Test showing multiple expectations
|
|
TEST_F(ProcessMockTest, MultipleFileOperations) {
|
|
using ::testing::_;
|
|
using ::testing::Return;
|
|
|
|
EXPECT_CALL(*mock_filesystem, exists(_))
|
|
.Times(2)
|
|
.WillOnce(Return(true))
|
|
.WillOnce(Return(false));
|
|
|
|
EXPECT_CALL(*mock_filesystem, read_file(_))
|
|
.WillOnce(Return("First file content\r\n"));
|
|
|
|
// Test multiple calls
|
|
EXPECT_TRUE(mock_filesystem->exists("/path1"));
|
|
EXPECT_EQ(mock_filesystem->read_file("/path1"), "First file content\r\n");
|
|
EXPECT_FALSE(mock_filesystem->exists("/path2"));
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|