You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
settings/tests/ui/network_join_test.cpp

156 lines
5.6 KiB
C++

// SPDX-FileCopyrightText: 2026 Reion Wong <reionwong@gmail.com>
// SPDX-License-Identifier: BSD-3-Clause
#include <gtest/gtest.h>
#include <memory>
#include <string>
#include <vector>
#include "cutefish/networkmanager/handler.h"
#include "pages/network/wlan/newnetworkdialog.h"
#include "ui/combo_box.h"
#include "ui/text_field.h"
#include "widgets/formdialog.h"
#include "window/settingswindow.h"
using namespace settings;
using namespace settings::network;
namespace nm = cutefish::networkmanager;
namespace {
struct JoinDialog : testing::Test
{
void SetUp() override
{
window = std::make_unique<SettingsWindow>();
window->reveal();
dialog = std::make_unique<NewNetworkDialog>(*window);
dialog->onJoinNetwork = [this](const std::string& device, const std::string& accessPoint,
const std::string& userName, const std::string& password) {
joins.push_back({device, accessPoint, userName, password});
};
dialog->onConnect = [this](const std::string& ssid, const std::string& userName, const std::string& password,
const std::string& type) { connects.push_back({ssid, userName, password, type}); };
}
const nm::WirelessNetwork library{"/org/freedesktop/NetworkManager/Devices/2", "Library", nm::SecurityType::Wpa2Eap};
const std::string libraryAccessPoint = "/org/freedesktop/NetworkManager/AccessPoint/5";
std::unique_ptr<SettingsWindow> window;
std::unique_ptr<NewNetworkDialog> dialog;
std::vector<std::vector<std::string>> joins;
std::vector<std::vector<std::string>> connects;
};
} // namespace
TEST_F(JoinDialog, JoinsAListedEnterpriseNetwork)
{
dialog->openNetwork(libraryAccessPoint, library);
ASSERT_TRUE(dialog->isOpen());
EXPECT_EQ(dialog->title(), "Join “Library”");
EXPECT_EQ(dialog->security(), "wpa2-eap");
// The network is known; only the sign-in is asked for, user name first.
EXPECT_FALSE(dialog->nameField()->isVisible());
EXPECT_FALSE(dialog->securityBox()->isVisible());
EXPECT_TRUE(dialog->userNameField()->isVisible());
EXPECT_TRUE(dialog->passwordField()->isVisible());
EXPECT_TRUE(dialog->userNameField()->hasFocus());
EXPECT_FALSE(dialog->canJoin());
dialog->userNameField()->setText("alice");
EXPECT_FALSE(dialog->canJoin());
dialog->passwordField()->setText("secret");
EXPECT_TRUE(dialog->canJoin());
dialog->join();
ASSERT_EQ(joins.size(), 1u);
EXPECT_EQ(joins[0], (std::vector<std::string>{library.device, libraryAccessPoint, "alice", "secret"}));
EXPECT_TRUE(connects.empty());
EXPECT_FALSE(dialog->isOpen());
}
TEST_F(JoinDialog, WpaEnterpriseKeepsItsKind)
{
dialog->openNetwork(libraryAccessPoint, nm::WirelessNetwork{library.device, "Old", nm::SecurityType::WpaEap});
ASSERT_TRUE(dialog->isOpen());
EXPECT_EQ(dialog->security(), "wpa-eap");
}
TEST_F(JoinDialog, CertificateNetworkCannotBeJoined)
{
dialog->openNetwork(libraryAccessPoint, nm::WirelessNetwork{library.device, "Secure", nm::SecurityType::Wpa3SuiteB192});
ASSERT_TRUE(dialog->isOpen());
EXPECT_TRUE(dialog->needsCertificate());
EXPECT_FALSE(dialog->userNameField()->isVisible());
EXPECT_FALSE(dialog->passwordField()->isVisible());
dialog->userNameField()->setText("alice");
dialog->passwordField()->setText("secret");
EXPECT_FALSE(dialog->canJoin());
dialog->join();
EXPECT_TRUE(joins.empty());
}
TEST_F(JoinDialog, GoneNetworkOpensNothing)
{
// Handler::wirelessNetwork() is empty once the access point has gone.
dialog->openNetwork(libraryAccessPoint, std::nullopt);
EXPECT_FALSE(dialog->isOpen());
}
TEST_F(JoinDialog, ClosingReturnsToHiddenNetworks)
{
dialog->openNetwork(libraryAccessPoint, library);
ASSERT_TRUE(dialog->isOpen());
dialog->userNameField()->setText("alice");
dialog->close();
EXPECT_FALSE(dialog->isOpen());
dialog->show();
ASSERT_TRUE(dialog->isOpen());
EXPECT_EQ(dialog->title(), "Add Other Network");
EXPECT_EQ(dialog->security(), "wpa2-wpa3");
EXPECT_EQ(dialog->userNameField()->text(), "");
EXPECT_TRUE(dialog->nameField()->isVisible());
EXPECT_TRUE(dialog->securityBox()->isVisible());
EXPECT_TRUE(dialog->nameField()->hasFocus());
dialog->nameField()->setText("Garden");
dialog->passwordField()->setText("garden pass");
dialog->join();
ASSERT_EQ(connects.size(), 1u);
EXPECT_EQ(connects[0], (std::vector<std::string>{"Garden", "", "garden pass", "wpa2-wpa3"}));
EXPECT_TRUE(joins.empty());
}
TEST_F(JoinDialog, PasswordsFitTheSecurity)
{
dialog->show();
dialog->nameField()->setText("Garden");
// WPA2/WPA3 passphrases are 8 to 63 characters.
dialog->passwordField()->setText("short");
EXPECT_FALSE(dialog->canJoin());
dialog->passwordField()->setText("long enough");
EXPECT_TRUE(dialog->canJoin());
// 64 characters are the key itself, in hexadecimal.
dialog->passwordField()->setText(std::string(64, 'a'));
EXPECT_TRUE(dialog->canJoin());
dialog->passwordField()->setText(std::string(64, 'z'));
EXPECT_FALSE(dialog->canJoin());
// WEP keys come in four lengths, the longer two hexadecimal; an open network needs none.
dialog->securityBox()->setCurrentIndex(1);
EXPECT_FALSE(dialog->canJoin());
dialog->passwordField()->setText("abcde");
EXPECT_TRUE(dialog->canJoin());
dialog->passwordField()->setText("0123456789");
EXPECT_TRUE(dialog->canJoin());
dialog->passwordField()->setText("garden key");
EXPECT_FALSE(dialog->canJoin());
dialog->securityBox()->setCurrentIndex(0);
dialog->passwordField()->setText("");
EXPECT_TRUE(dialog->canJoin());
}