const std = @import("std"); const api = @import("api"); const migrations = @import("main").migrations; const sql = @import("sql"); const util = @import("util"); const test_config = .{ .db = .{ .sqlite = .{ .sqlite_file_path = "file::memory:?cache=shared", .sqlite_is_uri = true, } }, }; const ApiSource = api.ApiSource; const root_user = "root"; const root_password = "password1234"; const admin_host = "example.com"; const admin_origin = "https://" ++ admin_host; fn makeDb(alloc: std.mem.Allocator) !sql.ConnPool { try util.seedThreadPrng(); var pool = try sql.ConnPool.init(test_config.db); { var db = try pool.acquire(); defer db.releaseConnection(); try migrations.up(db); try api.setupAdmin(db, admin_origin, root_user, root_password, alloc); } return pool; } fn connectAndLogin( api_source: *api.ApiSource, host: []const u8, username: []const u8, password: []const u8, alloc: std.mem.Allocator, ) !api.LoginResponse { var conn = try api_source.connectUnauthorized(host, alloc); defer conn.close(); return try util.deepClone(alloc, try conn.login(username, password)); } test "login as root" { const alloc = std.testing.allocator; var db = try makeDb(alloc); defer db.deinit(); var src = try ApiSource.init(&db); const login = try connectAndLogin(&src, admin_host, root_user, root_password, alloc); defer util.deepFree(alloc, login); var conn = try src.connectToken(admin_host, login.token, alloc); defer conn.close(); const auth = try conn.verifyAuthorization(); try std.testing.expectEqual(login.user_id, auth.id); try std.testing.expectEqualStrings(root_user, auth.username); try std.testing.expectEqualStrings(admin_host, auth.host); } test "create community" { const alloc = std.testing.allocator; var db = try makeDb(alloc); defer db.deinit(); var src = try ApiSource.init(&db); const login = try connectAndLogin(&src, admin_host, root_user, root_password, alloc); defer util.deepFree(alloc, login); var conn = try src.connectToken(admin_host, login.token, alloc); defer conn.close(); const host = "fedi.example.com"; const community = try conn.createCommunity("https://" ++ host); try std.testing.expectEqual(api.Community.Scheme.https, community.scheme); try std.testing.expectEqual(api.Community.Kind.local, community.kind); try std.testing.expect(community.owner_id == null); try std.testing.expectEqualStrings(host, community.host); try std.testing.expectEqualStrings(host, community.name); } test "create community and transfer to new owner" { const alloc = std.testing.allocator; var db = try makeDb(alloc); defer db.deinit(); var src = try ApiSource.init(&db); const root_login = try connectAndLogin(&src, admin_host, root_user, root_password, alloc); defer util.deepFree(alloc, root_login); const host = "fedi.example.com"; const invite = blk: { var conn = try src.connectToken(admin_host, root_login.token, alloc); defer conn.close(); const community = try conn.createCommunity("https://" ++ host); const invite = try conn.createInvite(.{ .to_community = community.id, .kind = .community_owner }); break :blk try util.deepClone(alloc, invite); }; defer util.deepFree(alloc, invite); const username = "testuser"; const password = root_password; { var conn = try src.connectUnauthorized(host, alloc); defer conn.close(); _ = try conn.register(username, password, .{ .invite_code = invite.code }); } const login = try connectAndLogin(&src, host, username, password, alloc); defer util.deepFree(alloc, login); var conn = try src.connectToken(host, login.token, alloc); defer conn.close(); const auth = try conn.verifyAuthorization(); try std.testing.expectEqual(login.user_id, auth.id); try std.testing.expectEqualStrings(username, auth.username); try std.testing.expectEqualStrings(host, auth.host); try std.testing.expectEqual(invite.community_id, auth.community_id); }