Page MenuHomePhorge

device-ops-test.cpp
No OneTemporary

Size
9 KB
Referenced Files
None
Subscribers
None

device-ops-test.cpp

/*
* This file is part of libkazv.
* SPDX-FileCopyrightText: 2023 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <libkazv-config.hpp>
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_predicate.hpp>
#include <catch2/matchers/catch_matchers_contains.hpp>
#include <boost/asio.hpp>
#include <asio-promise-handler.hpp>
#include <cursorutil.hpp>
#include <sdk-model.hpp>
#include <client/client.hpp>
#include "client-test-util.hpp"
#include "factory.hpp"
using namespace Kazv::Factory;
static RoomModel makeEncryptedRoom(const ComposedModifier<RoomModel> &mod)
{
return makeRoom(
withRoomEncrypted(true)
| withAttr(&RoomModel::shouldRotateSessionKey, false)
| mod
);
}
static auto getModel()
{
auto model = makeClient(
withDevice("@test1:test1.org",
makeDeviceKeyInfo(withDeviceId("device1") | withDeviceDisplayName("test1-device1")))
| withDevice("@test1:test1.org",
makeDeviceKeyInfo(withDeviceId("device2") | withDeviceDisplayName("test1-device2")))
);
return model;
}
static auto getModelWithEncryptedRooms()
{
auto model = makeClient(
withDevice("@test1:test1.org",
makeDeviceKeyInfo(withDeviceId("device1") | withDeviceDisplayName("test1-device1") | withDeviceTrustLevel(Unseen)))
| withDevice("@test1:test1.org",
makeDeviceKeyInfo(withDeviceId("device2") | withDeviceDisplayName("test1-device2") | withDeviceTrustLevel(Verified)))
| withDevice("@test1:test1.org",
makeDeviceKeyInfo(withDeviceId("device3") | withDeviceDisplayName("test1-device3") | withDeviceTrustLevel(Seen)))
| withDevice("@test2:test2.org",
makeDeviceKeyInfo(withDeviceId("device1") | withDeviceDisplayName("test2-device1") | withDeviceTrustLevel(Unseen)))
| withDevice("@test2:test2.org",
makeDeviceKeyInfo(withDeviceId("device2") | withDeviceDisplayName("test2-device2") | withDeviceTrustLevel(Blocked)))
| withDevice("@test2:test2.org",
makeDeviceKeyInfo(withDeviceId("device3") | withDeviceDisplayName("test2-device3") | withDeviceTrustLevel(Seen)))
| withRoom(makeEncryptedRoom(
withRoomId("!room1:tusooa.xyz")
| withRoomState({makeMemberEvent(withStateKey("@test1:test1.org"))})
))
| withRoom(makeEncryptedRoom(
withRoomId("!room2:tusooa.xyz")
| withRoomState({makeMemberEvent(withStateKey("@test2:test2.org"))})
))
| withRoom(makeEncryptedRoom(
withRoomId("!room3:tusooa.xyz")
| withRoomState({
makeMemberEvent(withStateKey("@test1:test1.org")),
makeMemberEvent(withStateKey("@test2:test2.org")),
})
))
);
return model;
}
using namespace Kazv::CursorOp;
using namespace Catch::Matchers;
TEST_CASE("devicesOfUser()", "[client][device-list-tracker]")
{
boost::asio::io_context io;
AsioPromiseHandler ph{io.get_executor()};
auto model = getModel();
auto store = createTestClientStoreFrom(model, ph);
auto client = Client(store.reader().map([](auto c) { return SdkModel{c}; }), store,
std::nullopt);
auto devices = +client.devicesOfUser("@test1:test1.org");
REQUIRE(devices.size() == 2);
REQUIRE_THAT(devices, Contains(Predicate<DeviceKeyInfo>([](auto d) { return d.deviceId == "device1"; })));
REQUIRE_THAT(devices, Contains(Predicate<DeviceKeyInfo>([](auto d) { return d.deviceId == "device2"; })));
}
TEST_CASE("setTrustLevel()", "[client][device-list-tracker]")
{
boost::asio::io_context io;
AsioPromiseHandler ph{io.get_executor()};
auto model = getModel();
auto store = createTestClientStoreFrom(model, ph);
auto client = Client(store.reader().map([](auto c) { return SdkModel{c}; }), store,
std::nullopt);
client.setDeviceTrustLevel("@test1:test1.org", "device1", Seen)
.then([client](auto s) {
REQUIRE(s.success());
REQUIRE_THAT((+client.devicesOfUser("@test1:test1.org")),
Contains(Predicate<DeviceKeyInfo>([](auto d) { return d.deviceId == "device1" && d.trustLevel == Seen; })));
});
io.run();
}
TEST_CASE("setTrustLevelNeededToSendKeys()", "[client][device-list-tracker]")
{
boost::asio::io_context io;
AsioPromiseHandler ph{io.get_executor()};
auto model = getModel();
auto store = createTestClientStoreFrom(model, ph);
auto client = Client(store.reader().map([](auto c) { return SdkModel{c}; }), store,
std::nullopt);
REQUIRE((+client.trustLevelNeededToSendKeys()) == Unseen);
client.setTrustLevelNeededToSendKeys(Verified)
.then([client](auto s) {
REQUIRE(s.success());
REQUIRE((+client.trustLevelNeededToSendKeys()) == Verified);
});
io.run();
}
TEST_CASE("maybeRotateSessions()", "[client][device-list-tracker]")
{
auto oldModel = getModelWithEncryptedRooms();
oldModel.trustLevelNeededToSendKeys = Seen;
WHEN("change a device display name")
{
auto newModel = oldModel;
withDevice("@test1:test1.org", makeDeviceKeyInfo(
withDeviceId("device1") | withDeviceDisplayName("some other things") | withDeviceTrustLevel(Unseen)))(newModel);
newModel.maybeRotateSessions(oldModel);
REQUIRE(!newModel.roomList.rooms["!room1:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(!newModel.roomList.rooms["!room2:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(!newModel.roomList.rooms["!room3:tusooa.xyz"].shouldRotateSessionKey);
}
WHEN("change from unseen to blocked")
{
auto [newModel, dontCareEffect] = ClientModel::update(oldModel, SetDeviceTrustLevelAction{"@test1:test1.org", "device1", Blocked});
REQUIRE(!newModel.roomList.rooms["!room1:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(!newModel.roomList.rooms["!room2:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(!newModel.roomList.rooms["!room3:tusooa.xyz"].shouldRotateSessionKey);
}
WHEN("change from verified to unseen")
{
auto [newModel, dontCareEffect] = ClientModel::update(oldModel, SetDeviceTrustLevelAction{"@test1:test1.org", "device2", Unseen});
REQUIRE(newModel.roomList.rooms["!room1:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(!newModel.roomList.rooms["!room2:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(newModel.roomList.rooms["!room3:tusooa.xyz"].shouldRotateSessionKey);
}
WHEN("change from verified to seen")
{
auto [newModel, dontCareEffect] = ClientModel::update(oldModel, SetDeviceTrustLevelAction{"@test1:test1.org", "device2", Seen});
REQUIRE(!newModel.roomList.rooms["!room1:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(!newModel.roomList.rooms["!room2:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(!newModel.roomList.rooms["!room3:tusooa.xyz"].shouldRotateSessionKey);
}
WHEN("change from verified to blocked")
{
auto [newModel, dontCareEffect] = ClientModel::update(oldModel, SetDeviceTrustLevelAction{"@test1:test1.org", "device2", Blocked});
REQUIRE(newModel.roomList.rooms["!room1:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(!newModel.roomList.rooms["!room2:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(newModel.roomList.rooms["!room3:tusooa.xyz"].shouldRotateSessionKey);
}
WHEN("change from unseen to verified")
{
auto [newModel, dontCareEffect] = ClientModel::update(oldModel, SetDeviceTrustLevelAction{"@test2:test2.org", "device1", Verified});
REQUIRE(!newModel.roomList.rooms["!room1:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(newModel.roomList.rooms["!room2:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(newModel.roomList.rooms["!room3:tusooa.xyz"].shouldRotateSessionKey);
}
}
TEST_CASE("maybeRotateSessions() when trustLevelNeededToSendKeys changed", "[client][device-list-tracker]")
{
auto oldModel = getModelWithEncryptedRooms();
oldModel.trustLevelNeededToSendKeys = Unseen;
WHEN("threshold didn't change")
{
auto newModel = oldModel;
newModel.maybeRotateSessions(oldModel);
REQUIRE(!newModel.roomList.rooms["!room1:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(!newModel.roomList.rooms["!room2:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(!newModel.roomList.rooms["!room3:tusooa.xyz"].shouldRotateSessionKey);
}
WHEN("threshold changed from unseen to blocked")
{
auto newModel = oldModel;
newModel.trustLevelNeededToSendKeys = Blocked;
newModel.maybeRotateSessions(oldModel);
REQUIRE(!newModel.roomList.rooms["!room1:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(newModel.roomList.rooms["!room2:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(newModel.roomList.rooms["!room3:tusooa.xyz"].shouldRotateSessionKey);
}
WHEN("threshold changed from unseen to seen")
{
auto newModel = oldModel;
newModel.trustLevelNeededToSendKeys = Seen;
newModel.maybeRotateSessions(oldModel);
REQUIRE(newModel.roomList.rooms["!room1:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(newModel.roomList.rooms["!room2:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(newModel.roomList.rooms["!room3:tusooa.xyz"].shouldRotateSessionKey);
}
WHEN("threshold changed from seen to verified")
{
oldModel.trustLevelNeededToSendKeys = Seen;
auto newModel = oldModel;
newModel.trustLevelNeededToSendKeys = Verified;
newModel.maybeRotateSessions(oldModel);
REQUIRE(newModel.roomList.rooms["!room1:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(newModel.roomList.rooms["!room2:tusooa.xyz"].shouldRotateSessionKey);
REQUIRE(newModel.roomList.rooms["!room3:tusooa.xyz"].shouldRotateSessionKey);
}
}

File Metadata

Mime Type
text/x-c
Expires
Tue, Jun 24, 6:13 AM (3 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
234719
Default Alt Text
device-ops-test.cpp (9 KB)

Event Timeline