refactor kstate, add stub user syncing function
This commit is contained in:
		
							parent
							
								
									4d8b74f61f
								
							
						
					
					
						commit
						f418d51e55
					
				
					 6 changed files with 181 additions and 143 deletions
				
			
		| 
						 | 
					@ -9,50 +9,15 @@ const { discord, sync, db } = passthrough
 | 
				
			||||||
const file = sync.require("../../matrix/file")
 | 
					const file = sync.require("../../matrix/file")
 | 
				
			||||||
/** @type {import("../../matrix/api")} */
 | 
					/** @type {import("../../matrix/api")} */
 | 
				
			||||||
const api = sync.require("../../matrix/api")
 | 
					const api = sync.require("../../matrix/api")
 | 
				
			||||||
 | 
					/** @type {import("../../matrix/kstate")} */
 | 
				
			||||||
function kstateStripConditionals(kstate) {
 | 
					const ks = sync.require("../../matrix/kstate")
 | 
				
			||||||
	for (const [k, content] of Object.entries(kstate)) {
 | 
					 | 
				
			||||||
		if ("$if" in content) {
 | 
					 | 
				
			||||||
			if (content.$if) delete content.$if
 | 
					 | 
				
			||||||
			else delete kstate[k]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return kstate
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function kstateToState(kstate) {
 | 
					 | 
				
			||||||
	const events = []
 | 
					 | 
				
			||||||
	for (const [k, content] of Object.entries(kstate)) {
 | 
					 | 
				
			||||||
		// conditional for whether a key is even part of the kstate (doing this declaratively on json is hard, so represent it as a property instead.)
 | 
					 | 
				
			||||||
		if ("$if" in content && !content.$if) continue
 | 
					 | 
				
			||||||
		delete content.$if
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		const [type, state_key] = k.split("/")
 | 
					 | 
				
			||||||
		assert.ok(typeof type === "string")
 | 
					 | 
				
			||||||
		assert.ok(typeof state_key === "string")
 | 
					 | 
				
			||||||
		events.push({type, state_key, content})
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return events
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * @param {import("../../types").Event.BaseStateEvent[]} events
 | 
					 | 
				
			||||||
 * @returns {any}
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
function stateToKState(events) {
 | 
					 | 
				
			||||||
	const kstate = {}
 | 
					 | 
				
			||||||
	for (const event of events) {
 | 
					 | 
				
			||||||
		kstate[event.type + "/" + event.state_key] = event.content
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return kstate
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {string} roomID
 | 
					 * @param {string} roomID
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
async function roomToKState(roomID) {
 | 
					async function roomToKState(roomID) {
 | 
				
			||||||
	const root = await api.getAllState(roomID)
 | 
						const root = await api.getAllState(roomID)
 | 
				
			||||||
	return stateToKState(root)
 | 
						return ks.stateToKState(root)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -60,33 +25,12 @@ async function roomToKState(roomID) {
 | 
				
			||||||
 * @params {any} kstate
 | 
					 * @params {any} kstate
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
function applyKStateDiffToRoom(roomID, kstate) {
 | 
					function applyKStateDiffToRoom(roomID, kstate) {
 | 
				
			||||||
	const events = kstateToState(kstate)
 | 
						const events = ks.kstateToState(kstate)
 | 
				
			||||||
	return Promise.all(events.map(({type, state_key, content}) =>
 | 
						return Promise.all(events.map(({type, state_key, content}) =>
 | 
				
			||||||
		api.sendState(roomID, type, state_key, content)
 | 
							api.sendState(roomID, type, state_key, content)
 | 
				
			||||||
	))
 | 
						))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function diffKState(actual, target) {
 | 
					 | 
				
			||||||
	const diff = {}
 | 
					 | 
				
			||||||
	// go through each key that it should have
 | 
					 | 
				
			||||||
	for (const key of Object.keys(target)) {
 | 
					 | 
				
			||||||
		if (key in actual) {
 | 
					 | 
				
			||||||
			// diff
 | 
					 | 
				
			||||||
			try {
 | 
					 | 
				
			||||||
				assert.deepEqual(actual[key], target[key])
 | 
					 | 
				
			||||||
			} catch (e) {
 | 
					 | 
				
			||||||
				// they differ. reassign the target
 | 
					 | 
				
			||||||
				diff[key] = target[key]
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			// not present, needs to be added
 | 
					 | 
				
			||||||
			diff[key] = target[key]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		// keys that are missing in "actual" will not be deleted on "target" (no action)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return diff
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * @param {import("discord-api-types/v10").APIGuildTextChannel} channel
 | 
					 * @param {import("discord-api-types/v10").APIGuildTextChannel} channel
 | 
				
			||||||
 * @param {import("discord-api-types/v10").APIGuild} guild
 | 
					 * @param {import("discord-api-types/v10").APIGuild} guild
 | 
				
			||||||
| 
						 | 
					@ -98,7 +42,7 @@ async function channelToKState(channel, guild) {
 | 
				
			||||||
	const avatarEventContent = {}
 | 
						const avatarEventContent = {}
 | 
				
			||||||
	if (guild.icon) {
 | 
						if (guild.icon) {
 | 
				
			||||||
		avatarEventContent.discord_path = file.guildIcon(guild)
 | 
							avatarEventContent.discord_path = file.guildIcon(guild)
 | 
				
			||||||
		avatarEventContent.url = await file.uploadDiscordFileToMxc(avatarEventContent.discord_path)
 | 
							avatarEventContent.url = await file.uploadDiscordFileToMxc(avatarEventContent.discord_path) // TODO: somehow represent future values in kstate (callbacks?), while still allowing for diffing, so test cases don't need to touch the media API
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const channelKState = {
 | 
						const channelKState = {
 | 
				
			||||||
| 
						 | 
					@ -138,7 +82,7 @@ async function createRoom(channel, guild, spaceID, kstate) {
 | 
				
			||||||
		preset: "private_chat",
 | 
							preset: "private_chat",
 | 
				
			||||||
		visibility: "private",
 | 
							visibility: "private",
 | 
				
			||||||
		invite: ["@cadence:cadence.moe"], // TODO
 | 
							invite: ["@cadence:cadence.moe"], // TODO
 | 
				
			||||||
		initial_state: kstateToState(kstate)
 | 
							initial_state: ks.kstateToState(kstate)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	db.prepare("INSERT INTO channel_room (channel_id, room_id) VALUES (?, ?)").run(channel.id, roomID)
 | 
						db.prepare("INSERT INTO channel_room (channel_id, room_id) VALUES (?, ?)").run(channel.id, roomID)
 | 
				
			||||||
| 
						 | 
					@ -204,12 +148,12 @@ async function _syncRoom(channelID, shouldActuallySync) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// sync channel state to room
 | 
							// sync channel state to room
 | 
				
			||||||
		const roomKState = await roomToKState(existing)
 | 
							const roomKState = await roomToKState(existing)
 | 
				
			||||||
		const roomDiff = diffKState(roomKState, channelKState)
 | 
							const roomDiff = ks.diffKState(roomKState, channelKState)
 | 
				
			||||||
		const roomApply = applyKStateDiffToRoom(existing, roomDiff)
 | 
							const roomApply = applyKStateDiffToRoom(existing, roomDiff)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// sync room as space member
 | 
							// sync room as space member
 | 
				
			||||||
		const spaceKState = await roomToKState(spaceID)
 | 
							const spaceKState = await roomToKState(spaceID)
 | 
				
			||||||
		const spaceDiff = diffKState(spaceKState, {
 | 
							const spaceDiff = ks.diffKState(spaceKState, {
 | 
				
			||||||
			[`m.space.child/${existing}`]: {
 | 
								[`m.space.child/${existing}`]: {
 | 
				
			||||||
				via: ["cadence.moe"] // TODO: use the proper server
 | 
									via: ["cadence.moe"] // TODO: use the proper server
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -241,8 +185,4 @@ module.exports.createRoom = createRoom
 | 
				
			||||||
module.exports.ensureRoom = ensureRoom
 | 
					module.exports.ensureRoom = ensureRoom
 | 
				
			||||||
module.exports.syncRoom = syncRoom
 | 
					module.exports.syncRoom = syncRoom
 | 
				
			||||||
module.exports.createAllForGuild = createAllForGuild
 | 
					module.exports.createAllForGuild = createAllForGuild
 | 
				
			||||||
module.exports.kstateToState = kstateToState
 | 
					 | 
				
			||||||
module.exports.stateToKState = stateToKState
 | 
					 | 
				
			||||||
module.exports.diffKState = diffKState
 | 
					 | 
				
			||||||
module.exports.channelToKState = channelToKState
 | 
					module.exports.channelToKState = channelToKState
 | 
				
			||||||
module.exports.kstateStripConditionals = kstateStripConditionals
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,80 +1,8 @@
 | 
				
			||||||
const {kstateToState, stateToKState, diffKState, channelToKState, kstateStripConditionals} = require("./create-room")
 | 
					const {channelToKState} = require("./create-room")
 | 
				
			||||||
 | 
					const {kstateStripConditionals} = require("../../matrix/kstate")
 | 
				
			||||||
const {test} = require("supertape")
 | 
					const {test} = require("supertape")
 | 
				
			||||||
const testData = require("../../test/data")
 | 
					const testData = require("../../test/data")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test("kstate2state: general", t => {
 | 
					 | 
				
			||||||
	t.deepEqual(kstateToState({
 | 
					 | 
				
			||||||
		"m.room.name/": {name: "test name"},
 | 
					 | 
				
			||||||
		"m.room.member/@cadence:cadence.moe": {membership: "join"}
 | 
					 | 
				
			||||||
	}), [
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			type: "m.room.name",
 | 
					 | 
				
			||||||
			state_key: "",
 | 
					 | 
				
			||||||
			content: {
 | 
					 | 
				
			||||||
				name: "test name"
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			type: "m.room.member",
 | 
					 | 
				
			||||||
			state_key: "@cadence:cadence.moe",
 | 
					 | 
				
			||||||
			content: {
 | 
					 | 
				
			||||||
				membership: "join"
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	])
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test("state2kstate: general", t => {
 | 
					 | 
				
			||||||
	t.deepEqual(stateToKState([
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			type: "m.room.name",
 | 
					 | 
				
			||||||
			state_key: "",
 | 
					 | 
				
			||||||
			content: {
 | 
					 | 
				
			||||||
				name: "test name"
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			type: "m.room.member",
 | 
					 | 
				
			||||||
			state_key: "@cadence:cadence.moe",
 | 
					 | 
				
			||||||
			content: {
 | 
					 | 
				
			||||||
				membership: "join"
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	]), {
 | 
					 | 
				
			||||||
		"m.room.name/": {name: "test name"},
 | 
					 | 
				
			||||||
		"m.room.member/@cadence:cadence.moe": {membership: "join"}
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test("diffKState: detects edits", t => {
 | 
					 | 
				
			||||||
	t.deepEqual(
 | 
					 | 
				
			||||||
		diffKState({
 | 
					 | 
				
			||||||
			"m.room.name/": {name: "test name"},
 | 
					 | 
				
			||||||
			"same/": {a: 2}
 | 
					 | 
				
			||||||
		}, {
 | 
					 | 
				
			||||||
			"m.room.name/": {name: "edited name"},
 | 
					 | 
				
			||||||
			"same/": {a: 2}
 | 
					 | 
				
			||||||
		}),
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"m.room.name/": {name: "edited name"}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test("diffKState: detects new properties", t => {
 | 
					 | 
				
			||||||
	t.deepEqual(
 | 
					 | 
				
			||||||
		diffKState({
 | 
					 | 
				
			||||||
			"m.room.name/": {name: "test name"},
 | 
					 | 
				
			||||||
		}, {
 | 
					 | 
				
			||||||
			"m.room.name/": {name: "test name"},
 | 
					 | 
				
			||||||
			"new/": {a: 2}
 | 
					 | 
				
			||||||
		}),
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"new/": {a: 2}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
test("channel2room: general", async t => {
 | 
					test("channel2room: general", async t => {
 | 
				
			||||||
	t.deepEqual(
 | 
						t.deepEqual(
 | 
				
			||||||
		kstateStripConditionals(await channelToKState(testData.channel.general, testData.guild.general).then(x => x.channelKState)),
 | 
							kstateStripConditionals(await channelToKState(testData.channel.general, testData.guild.general).then(x => x.channelKState)),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,5 +78,15 @@ async function ensureSimJoined(user, roomID) {
 | 
				
			||||||
	return mxid
 | 
						return mxid
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {import("discord-api-types/v10").APIUser} user
 | 
				
			||||||
 | 
					 * @param {Required<Omit<import("discord-api-types/v10").APIGuildMember, "user">>} member
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					async function memberToStateContent(user, member) {
 | 
				
			||||||
 | 
						return {
 | 
				
			||||||
 | 
							displayname: member.nick || user.username
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports.ensureSim = ensureSim
 | 
					module.exports.ensureSim = ensureSim
 | 
				
			||||||
module.exports.ensureSimJoined = ensureSimJoined
 | 
					module.exports.ensureSimJoined = ensureSimJoined
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										65
									
								
								matrix/kstate.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								matrix/kstate.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,65 @@
 | 
				
			||||||
 | 
					// @ts-check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const assert = require("assert")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Mutates the input. */
 | 
				
			||||||
 | 
					function kstateStripConditionals(kstate) {
 | 
				
			||||||
 | 
						for (const [k, content] of Object.entries(kstate)) {
 | 
				
			||||||
 | 
							// conditional for whether a key is even part of the kstate (doing this declaratively on json is hard, so represent it as a property instead.)
 | 
				
			||||||
 | 
							if ("$if" in content) {
 | 
				
			||||||
 | 
								if (content.$if) delete content.$if
 | 
				
			||||||
 | 
								else delete kstate[k]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return kstate
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function kstateToState(kstate) {
 | 
				
			||||||
 | 
						const events = []
 | 
				
			||||||
 | 
						kstateStripConditionals(kstate)
 | 
				
			||||||
 | 
						for (const [k, content] of Object.entries(kstate)) {
 | 
				
			||||||
 | 
							const [type, state_key] = k.split("/")
 | 
				
			||||||
 | 
							assert.ok(typeof type === "string")
 | 
				
			||||||
 | 
							assert.ok(typeof state_key === "string")
 | 
				
			||||||
 | 
							events.push({type, state_key, content})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return events
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * @param {import("../types").Event.BaseStateEvent[]} events
 | 
				
			||||||
 | 
					 * @returns {any}
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function stateToKState(events) {
 | 
				
			||||||
 | 
						const kstate = {}
 | 
				
			||||||
 | 
						for (const event of events) {
 | 
				
			||||||
 | 
							kstate[event.type + "/" + event.state_key] = event.content
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return kstate
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function diffKState(actual, target) {
 | 
				
			||||||
 | 
						const diff = {}
 | 
				
			||||||
 | 
						// go through each key that it should have
 | 
				
			||||||
 | 
						for (const key of Object.keys(target)) {
 | 
				
			||||||
 | 
							if (key in actual) {
 | 
				
			||||||
 | 
								// diff
 | 
				
			||||||
 | 
								try {
 | 
				
			||||||
 | 
									assert.deepEqual(actual[key], target[key])
 | 
				
			||||||
 | 
								} catch (e) {
 | 
				
			||||||
 | 
									// they differ. reassign the target
 | 
				
			||||||
 | 
									diff[key] = target[key]
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// not present, needs to be added
 | 
				
			||||||
 | 
								diff[key] = target[key]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// keys that are missing in "actual" will not be deleted on "target" (no action)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return diff
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports.kstateStripConditionals = kstateStripConditionals
 | 
				
			||||||
 | 
					module.exports.kstateToState = kstateToState
 | 
				
			||||||
 | 
					module.exports.stateToKState = stateToKState
 | 
				
			||||||
 | 
					module.exports.diffKState = diffKState
 | 
				
			||||||
							
								
								
									
										94
									
								
								matrix/kstate.test.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								matrix/kstate.test.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,94 @@
 | 
				
			||||||
 | 
					const {kstateToState, stateToKState, diffKState, kstateStripConditionals} = require("./kstate")
 | 
				
			||||||
 | 
					const {test} = require("supertape")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("kstate strip: strips false conditions", t => {
 | 
				
			||||||
 | 
					   t.deepEqual(kstateStripConditionals({
 | 
				
			||||||
 | 
					      a: {$if: false, value: 2},
 | 
				
			||||||
 | 
					      b: {value: 4}
 | 
				
			||||||
 | 
					   }), {
 | 
				
			||||||
 | 
					      b: {value: 4}
 | 
				
			||||||
 | 
					   })
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("kstate strip: keeps true conditions while removing $if", t => {
 | 
				
			||||||
 | 
					   t.deepEqual(kstateStripConditionals({
 | 
				
			||||||
 | 
					      a: {$if: true, value: 2},
 | 
				
			||||||
 | 
					      b: {value: 4}
 | 
				
			||||||
 | 
					   }), {
 | 
				
			||||||
 | 
					      a: {value: 2},
 | 
				
			||||||
 | 
					      b: {value: 4}
 | 
				
			||||||
 | 
					   })
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("kstate2state: general", t => {
 | 
				
			||||||
 | 
						t.deepEqual(kstateToState({
 | 
				
			||||||
 | 
							"m.room.name/": {name: "test name"},
 | 
				
			||||||
 | 
							"m.room.member/@cadence:cadence.moe": {membership: "join"}
 | 
				
			||||||
 | 
						}), [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								type: "m.room.name",
 | 
				
			||||||
 | 
								state_key: "",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									name: "test name"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								type: "m.room.member",
 | 
				
			||||||
 | 
								state_key: "@cadence:cadence.moe",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									membership: "join"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						])
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("state2kstate: general", t => {
 | 
				
			||||||
 | 
						t.deepEqual(stateToKState([
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								type: "m.room.name",
 | 
				
			||||||
 | 
								state_key: "",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									name: "test name"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								type: "m.room.member",
 | 
				
			||||||
 | 
								state_key: "@cadence:cadence.moe",
 | 
				
			||||||
 | 
								content: {
 | 
				
			||||||
 | 
									membership: "join"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						]), {
 | 
				
			||||||
 | 
							"m.room.name/": {name: "test name"},
 | 
				
			||||||
 | 
							"m.room.member/@cadence:cadence.moe": {membership: "join"}
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("diffKState: detects edits", t => {
 | 
				
			||||||
 | 
						t.deepEqual(
 | 
				
			||||||
 | 
							diffKState({
 | 
				
			||||||
 | 
								"m.room.name/": {name: "test name"},
 | 
				
			||||||
 | 
								"same/": {a: 2}
 | 
				
			||||||
 | 
							}, {
 | 
				
			||||||
 | 
								"m.room.name/": {name: "edited name"},
 | 
				
			||||||
 | 
								"same/": {a: 2}
 | 
				
			||||||
 | 
							}),
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"m.room.name/": {name: "edited name"}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("diffKState: detects new properties", t => {
 | 
				
			||||||
 | 
						t.deepEqual(
 | 
				
			||||||
 | 
							diffKState({
 | 
				
			||||||
 | 
								"m.room.name/": {name: "test name"},
 | 
				
			||||||
 | 
							}, {
 | 
				
			||||||
 | 
								"m.room.name/": {name: "test name"},
 | 
				
			||||||
 | 
								"new/": {a: 2}
 | 
				
			||||||
 | 
							}),
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"new/": {a: 2}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,8 @@ const sync = new HeatSync({watchFS: false})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Object.assign(passthrough, { config, sync, db })
 | 
					Object.assign(passthrough, { config, sync, db })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require("../matrix/kstate.test")
 | 
				
			||||||
 | 
					require("../matrix/api.test")
 | 
				
			||||||
require("../matrix/read-registration.test")
 | 
					require("../matrix/read-registration.test")
 | 
				
			||||||
require("../d2m/actions/create-room.test")
 | 
					require("../d2m/actions/create-room.test")
 | 
				
			||||||
require("../d2m/converters/user-to-mxid.test")
 | 
					require("../d2m/converters/user-to-mxid.test")
 | 
				
			||||||
require("../matrix/api.test")
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue