Skip to content
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
8 changes: 7 additions & 1 deletion tests/coop/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,18 @@ add_executable(coop_tests ${COOP_SRC}
${CMAKE_CURRENT_SOURCE_DIR}/phonehelper_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/networkutil_stub_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/taskdialog_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/commandparser_test.cpp)
${CMAKE_CURRENT_SOURCE_DIR}/commandparser_test.cpp
${CMAKE_SOURCE_DIR}/tests/session_core/protoendpoint_test.cpp
${CMAKE_SOURCE_DIR}/tests/session_core/protoclient_server_test.cpp
${CMAKE_SOURCE_DIR}/tests/session_core/cooperationcore_test.cpp
${CMAKE_SOURCE_DIR}/tests/session_core/discover_extra_test.cpp)
target_compile_options(coop_tests PRIVATE -fno-access-control -fprofile-arcs -ftest-coverage)
target_compile_definitions(coop_tests PRIVATE EXECUTABLE_PROG_DIR="${CMAKE_BINARY_DIR}" ENABLE_PHONE=1)
target_include_directories(coop_tests PRIVATE
${CMAKE_SOURCE_DIR}/src ${CD}
${CMAKE_SOURCE_DIR}/src/lib/common
${CMAKE_SOURCE_DIR}/src/lib/common/session
${CMAKE_SOURCE_DIR}/tests/common
${CMAKE_SOURCE_DIR}/3rdparty/QtZeroConf
${CD}/gui/win)
target_link_libraries(coop_tests PRIVATE
Expand Down
4 changes: 3 additions & 1 deletion tests/coop_gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ add_executable(coop_gui_tests ${COOP_GUI_SRC}
${CMAKE_CURRENT_SOURCE_DIR}/mainwindow_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/settingdialog_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/discovercontroller_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/backgroundwidget_test.cpp)
${CMAKE_CURRENT_SOURCE_DIR}/backgroundwidget_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/vncrecvthread_vncsendworker_test.cpp
${CMAKE_CURRENT_SOURCE_DIR}/screenmirroringwindow_test.cpp)
target_compile_options(coop_gui_tests PRIVATE -fno-access-control -fprofile-arcs -ftest-coverage)
target_compile_definitions(coop_gui_tests PRIVATE EXECUTABLE_PROG_DIR="${CMAKE_BINARY_DIR}" ENABLE_PHONE=1)
target_include_directories(coop_gui_tests PRIVATE
Expand Down
87 changes: 87 additions & 0 deletions tests/coop_gui/screenmirroringwindow_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

#include <gtest/gtest.h>

Check warning on line 4 in tests/coop_gui/screenmirroringwindow_test.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <gtest/gtest.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QSize>

Check warning on line 5 in tests/coop_gui/screenmirroringwindow_test.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QSize> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QSignalSpy>

Check warning on line 6 in tests/coop_gui/screenmirroringwindow_test.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QSignalSpy> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <cstdlib>

Check warning on line 7 in tests/coop_gui/screenmirroringwindow_test.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <cstdlib> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <string>

Check warning on line 8 in tests/coop_gui/screenmirroringwindow_test.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <string> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include "gui/phone/screenmirroringwindow.h"

Check warning on line 10 in tests/coop_gui/screenmirroringwindow_test.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: "gui/phone/screenmirroringwindow.h" not found.
#include "gui/phone/vncviewer.h"

Check warning on line 11 in tests/coop_gui/screenmirroringwindow_test.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: "gui/phone/vncviewer.h" not found.

using cooperation_core::ScreenMirroringWindow;
using cooperation_core::LockScreenWidget;

TEST(ScreenMirroringWindowTest, ConstructDoesNotCrash)
{
ScreenMirroringWindow w("TestDevice");
SUCCEED();
}

TEST(ScreenMirroringWindowTest, DestructorStopsVncViewer)
{
auto *w = new ScreenMirroringWindow("TestDevice");
delete w;
SUCCEED();
}

TEST(ScreenMirroringWindowTest, InitSizebyView)
{
ScreenMirroringWindow w("TestDevice");
QSize size(1080, 2400);
EXPECT_NO_FATAL_FAILURE(w.initSizebyView(size));
}

TEST(ScreenMirroringWindowTest, ConnectVncServerDoesNotCrash)
{
ScreenMirroringWindow w("TestDevice");
// Will try to connect but fail since no server. Won't crash.
const char *pwd = std::getenv("TEST_VNC_PASSWORD");
std::string password = pwd ? pwd : "";
EXPECT_NO_FATAL_FAILURE(w.connectVncServer("127.0.0.1", 5900, password.c_str()));
}

TEST(ScreenMirroringWindowTest, HandleSizeChangePortrait)
{
ScreenMirroringWindow w("TestDevice");
// Portrait size (w < h)
EXPECT_NO_FATAL_FAILURE(w.handleSizeChange(QSize(360, 800)));
}

TEST(ScreenMirroringWindowTest, HandleSizeChangeLandscape)
{
ScreenMirroringWindow w("TestDevice");
// Landscape size (w > h)
EXPECT_NO_FATAL_FAILURE(w.handleSizeChange(QSize(800, 360)));
}

TEST(ScreenMirroringWindowTest, HandleSizeChangeSecondCall)
{
ScreenMirroringWindow w("TestDevice");
w.handleSizeChange(QSize(360, 800));
// Second call should not reposition
EXPECT_NO_FATAL_FAILURE(w.handleSizeChange(QSize(360, 800)));
}

TEST(ScreenMirroringWindowTest, ButtonClickedSignal)
{
ScreenMirroringWindow w("TestDevice");
QSignalSpy spy(&w, &ScreenMirroringWindow::buttonClicked);
EXPECT_EQ(spy.count(), 0);
}

// ============ LockScreenWidget ============

TEST(LockScreenWidgetTest, ConstructDoesNotCrash)
{
LockScreenWidget w;
SUCCEED();
}

TEST(LockScreenWidgetTest, PaintEventDoesNotCrash)
{
LockScreenWidget w;
w.repaint();
SUCCEED();
}
89 changes: 89 additions & 0 deletions tests/coop_gui/vncrecvthread_vncsendworker_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

#include <gtest/gtest.h>

Check warning on line 4 in tests/coop_gui/vncrecvthread_vncsendworker_test.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <gtest/gtest.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QImage>

Check warning on line 5 in tests/coop_gui/vncrecvthread_vncsendworker_test.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QImage> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QSignalSpy>

Check warning on line 6 in tests/coop_gui/vncrecvthread_vncsendworker_test.cpp

View workflow job for this annotation

GitHub Actions / static-check / static-check

Include file: <QSignalSpy> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QThread>
#include <memory>
#include <cstring>

#include "gui/phone/vncrecvthread.h"
#include "gui/phone/vncsendworker.h"
#include "stub.h"

#include <rfb/rfbclient.h>

// Stub libvncclient functions to avoid real network calls
static rfbBool stub_SendPointerEvent(rfbClient *, int, int, int) { return true; }
static rfbBool stub_SendKeyEvent(rfbClient *, uint32_t, rfbBool) { return true; }
static rfbBool stub_SendIncrementalFramebufferUpdateRequest(rfbClient *) { return true; }

// ============ VNCRecvThread ============

TEST(VNCRecvThreadTest, ConstructDefault)
{
VNCRecvThread t;
SUCCEED();
}

TEST(VNCRecvThreadTest, StopRunWhenNotRunning)
{
VNCRecvThread t;
EXPECT_NO_FATAL_FAILURE(t.stopRun());
}

TEST(VNCRecvThreadTest, StartAndStopCycle)
{
VNCRecvThread t;
auto fakeClient = std::make_unique<rfbClient>();
memset(fakeClient.get(), 0, sizeof(rfbClient));

t.startRun(fakeClient.get());
// Thread starts, WaitForMessage on fake client fails quickly
QThread::msleep(100);

t.stopRun();
ASSERT_TRUE(t.wait(2000)) << "Thread did not stop in time";
}

TEST(VNCRecvThreadTest, StopRunTwiceSafe)
{
VNCRecvThread t;
t.stopRun();
t.stopRun();
SUCCEED();
}

// ============ VNCSendWorker ============

TEST(VNCSendWorkerTest, ConstructDoesNotCrash)
{
VNCSendWorker w;
SUCCEED();
}

TEST(VNCSendWorkerTest, SendMouseUpdateMsgDoesNotCrash)
{
Stub stub;
stub.set(SendPointerEvent, stub_SendPointerEvent);
stub.set(SendIncrementalFramebufferUpdateRequest, stub_SendIncrementalFramebufferUpdateRequest);

VNCSendWorker w;
auto fakeClient = std::make_unique<rfbClient>();
memset(fakeClient.get(), 0, sizeof(rfbClient));
EXPECT_NO_FATAL_FAILURE(w.sendMouseUpdateMsg(fakeClient.get(), 100, 200, 1));
}

TEST(VNCSendWorkerTest, SendKeyUpdateMsgDoesNotCrash)
{
Stub stub;
stub.set(SendKeyEvent, stub_SendKeyEvent);
stub.set(SendIncrementalFramebufferUpdateRequest, stub_SendIncrementalFramebufferUpdateRequest);

VNCSendWorker w;
auto fakeClient = std::make_unique<rfbClient>();
memset(fakeClient.get(), 0, sizeof(rfbClient));
EXPECT_NO_FATAL_FAILURE(w.sendKeyUpdateMsg(fakeClient.get(), 0x41, true));
EXPECT_NO_FATAL_FAILURE(w.sendKeyUpdateMsg(fakeClient.get(), 0x41, false));
}
157 changes: 157 additions & 0 deletions tests/coop_gui/vncviewer_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
#include <gtest/gtest.h>
#include <QSignalSpy>
#include <QSize>
#include <QMouseEvent>
#include <QApplication>
#include <QBrush>
#include <cstdlib>
#include <string>
#include <rfb/rfbclient.h>
#include <rfb/keysym.h>
#include "gui/phone/vncviewer.h"
Expand Down Expand Up @@ -138,3 +143,155 @@ TEST(VncViewerTest, OnShortcutActionBackHomeRecentsWithStubbedSendKey)
EXPECT_NO_FATAL_FAILURE(v.onShortcutAction(1)); // HOME → Home
EXPECT_NO_FATAL_FAILURE(v.onShortcutAction(2)); // RECENTS → PageUp
}

// ============ setServes ============

TEST(VncViewerTest, SetServesStoresConnectionInfo)
{
VncViewer v;
const char *pwd = std::getenv("TEST_VNC_PASSWORD");
std::string password = pwd ? pwd : "";
v.setServes("192.168.1.100", 5900, password);
SUCCEED(); // stores into private fields
}

// ============ stop (not connected → early return) ============

TEST(VncViewerTest, StopWhenNotConnectedEarlyReturn)
{
VncViewer v;
access_private_field::VncViewerm_connected(v) = false;
EXPECT_NO_FATAL_FAILURE(v.stop());
}

// ============ updateImage ============

TEST(VncViewerTest, UpdateImageNullImageIgnored)
{
VncViewer v;
QImage nullImg;
EXPECT_NO_FATAL_FAILURE(v.updateImage(nullImg));
}

TEST(VncViewerTest, UpdateImageValidImageDoesNotCrash)
{
VncViewer v;
access_private_field::VncViewerm_connected(v) = true;
QImage img(100, 200, QImage::Format_RGBA8888);
img.fill(Qt::red);
EXPECT_NO_FATAL_FAILURE(v.updateImage(img));
}

// ============ clearSurface ============

TEST(VncViewerTest, ClearSurfaceNotConnected)
{
VncViewer v;
access_private_field::VncViewerm_connected(v) = false;
EXPECT_NO_FATAL_FAILURE(v.clearSurface());
}

// ============ setSurfaceSize (via clearSurface) ============

TEST(VncViewerTest, SetSurfaceSizeInvalidSizeIgnored)
{
VncViewer v;
// setSurfaceSize is private but clearSurface calls it
// When not connected, clearSurface returns early
EXPECT_NO_FATAL_FAILURE(v.clearSurface());
}

// ============ frameTimerTimeout ============

TEST(VncViewerTest, FrameTimerTimeoutDoesNotCrash)
{
VncViewer v;
EXPECT_NO_FATAL_FAILURE(v.frameTimerTimeout());
}

// ============ paintEvent (not connected → draws "Disconnected") ============

TEST(VncViewerTest, PaintEventDisconnectedState)
{
VncViewer v;
access_private_field::VncViewerm_connected(v) = false;
v.repaint();
SUCCEED();
}

TEST(VncViewerTest, PaintEventConnectedNoImage)
{
VncViewer v;
access_private_field::VncViewerm_connected(v) = true;
v.repaint();
SUCCEED();
}

// ============ resizeEvent ============

TEST(VncViewerTest, ResizeEventDoesNotCrash)
{
VncViewer v;
v.resize(200, 400);
SUCCEED();
}

// ============ backgroundBrush / scaled setters ============

TEST(VncViewerTest, BackgroundBrushSetterGetter)
{
VncViewer v;
QBrush brush(Qt::blue);
v.setBackgroundBrush(brush);
EXPECT_EQ(v.backgroundBrush(), brush);
}

TEST(VncViewerTest, ScaledSetterGetter)
{
VncViewer v;
v.setScaled(false);
EXPECT_FALSE(v.scaled());
v.setScaled(true);
EXPECT_TRUE(v.scaled());
}

// ============ updateSurface ============

TEST(VncViewerTest, UpdateSurfaceDoesNotCrash)
{
VncViewer v;
EXPECT_NO_FATAL_FAILURE(v.updateSurface());
}

// ============ closeEvent ============

TEST(VncViewerTest, CloseEventEmitsSignal)
{
VncViewer v;
QSignalSpy spy(&v, &VncViewer::fullWindowCloseSignal);
v.close();
EXPECT_EQ(spy.count(), 1);
}

// ============ mouse event handlers (just accept) ============

TEST(VncViewerTest, MousePressEventAccepts)
{
VncViewer v;
QMouseEvent press(QEvent::MouseButtonPress, QPoint(10, 10), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
EXPECT_NO_FATAL_FAILURE(QApplication::sendEvent(&v, &press));
}

TEST(VncViewerTest, MouseMoveEventAccepts)
{
VncViewer v;
QMouseEvent move(QEvent::MouseMove, QPoint(20, 20), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
EXPECT_NO_FATAL_FAILURE(QApplication::sendEvent(&v, &move));
}

TEST(VncViewerTest, MouseReleaseEventAccepts)
{
VncViewer v;
QMouseEvent release(QEvent::MouseButtonRelease, QPoint(10, 10), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
EXPECT_NO_FATAL_FAILURE(QApplication::sendEvent(&v, &release));
}
Loading
Loading