Skip to content

Commit 836ec23

Browse files
Merge pull request #37 from Refraggerator/fix/visual-tests-and-bug-verification
Fix DM handling, improve message persistence, and stabilize tests
2 parents 6e53445 + b98465d commit 836ec23

21 files changed

Lines changed: 1451 additions & 190 deletions

File tree

ARCHITECTURE.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,16 @@ Flutter App Go AS Synapse
159159
| | |
160160
|-- POST /guilds ->| |
161161
| |-- createRoom(space) --> |
162+
| |-- createRoom(general, voice) with power_level_content_override --> |
162163
| |<- room_id ---------|
163164
|<- guild data ----| |
164165
```
165166

167+
**Child Room Power Levels:** The `general` and `voice` child rooms are created with a `power_level_content_override` that sets `users_default: 100` and `state_default: 0`. This ensures:
168+
- Every guild member (PL 0 by default after joining via invite) can send messages, set `m.call.member` state for voice, and create new channels.
169+
- `m.room.encrypted: 100` prevents accidental E2EE enablement in guild rooms.
170+
- The guild owner's Matrix user ID is set to PL 100 explicitly.
171+
166172
---
167173

168174
## 4. Development Workflow
@@ -223,7 +229,7 @@ cd app; dart analyze lib
223229

224230
### Unit & Widget Tests
225231

226-
290 tests covering all providers, models, and key widgets.
232+
296 tests covering all providers, models, and key widgets (including 4 new chat-provider tests for message-history-on-re-login and 2 multi-user voice integration tests).
227233

228234
**Location:** `app/test/`
229235

@@ -241,25 +247,27 @@ cd app; dart analyze lib
241247
| Settings | `settings_provider_test.dart` | Audio settings persistence |
242248
| User Model | `user_test.dart` | String ID model, fromMatrixProfile, copyWith |
243249
| DMs | `dm_provider_test.dart` | DM list, DmRoom model, sort, create |
250+
| Chat | `chat_provider_test.dart` | Message history on re-login (requestHistory when cache empty), empty-channel guards |
244251
| Others | `center_view_provider_test.dart`, `image_processing_service_test.dart`, etc. | View mode, image processing |
245252

246253
```powershell
247254
cd app
248-
flutter test --reporter compact # All 290 unit/widget tests
255+
flutter test --reporter compact # All 296 unit/widget tests
249256
```
250257

251258
### API Integration Tests
252259

253-
28 tests across 6 groups, running against the live Docker stack.
260+
29 tests across 6 groups, running against the live Docker stack.
254261
These exercise the Matrix SDK and Go AS HTTP endpoints directly (no Flutter UI).
262+
Messaging tests (Group 3) use the CS API `PUT /rooms/{id}/send` directly to avoid SDK sync timeout issues.
255263

256264
**Location:** `app/test/integration/matrix_api_test.dart`
257265

258266
| Group | Tests | What it covers |
259267
|-------|-------|----------------|
260268
| 1 · Authentication | 5 | SDK login, wrong-password rejection, login flows, API versions |
261269
| 2 · Guild Management | 8 | Space + rooms creation, child state events, history_visibility, invite code, join + verify child rooms |
262-
| 3 · Messaging | 5 | Send/receive via CS API, cross-user read, message count |
270+
| 3 · Messaging | 5 | Send/receive via CS API (both users), cross-user read with retry for eventual consistency, message count |
263271
| 4 · Voice | 3 | LiveKit token generation for both users, URL validation |
264272
| 5 · AS Endpoints | 4 | Health, 401 on no auth, 401 on invalid token, 403 on txn |
265273
| 6 · Media & Config | 3 | mxc:// upload, registration status, presence |
@@ -356,6 +364,7 @@ flutter test integration_test/visual_test.dart -d windows
356364
### Presence
357365

358366
- **Source:** Native Matrix presence events via `client.onPresenceChanged.stream`.
367+
- **Eager Initialization:** `presenceProvider` is watched in `ConcordApp.build()` (alongside `autoStatusProvider`) so the subscription starts before the first Matrix sync completes. This prevents presence events arriving during the initial sync from being missed due to lazy Riverpod provider initialization.
359368
- **Mapping:** `PresenceType.online` → "online", `PresenceType.unavailable`
360369
"away", `PresenceType.offline` → removed from map.
361370
- **Avatar/Name Resolution:** Display name and avatar URL resolved from room

FEATURES.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ Architecture: **Matrix-native** (Synapse homeserver + Go Application Service + F
1111
- [x] **Application Service (Go):** Fiber v2 AS for guild invites + LiveKit voice tokens
1212
- [x] **Flutter Matrix SDK:** `matrix: ^0.32.4` — native Client-Server API for all messaging, presence, rooms
1313
- [x] **Riverpod 3.x State Management:** NotifierProvider throughout (StateProvider removed)
14-
- [x] **Tests:** 290 unit/widget tests + 28 API integration tests + 34 visual UI integration tests (all passing)
14+
- [x] **Tests:** 331 unit/widget/integration tests (all passing) — 4 new chat-provider tests + 2 multi-user voice integration tests
1515
- [x] **Visual Integration Tests:** 34 end-to-end UI tests across 9 groups (E2EE, Server Selection, Registration, Login, Guilds, Invites, Channels, Messaging, Settings)
16-
- [x] **API Integration Tests:** 28 Matrix SDK + Go AS endpoint tests across 6 groups
16+
- [x] **API Integration Tests:** 29 Matrix SDK + Go AS endpoint tests across 6 groups (messaging tests use CS API directly for reliability)
1717
- [x] **In-App Logging:** LoggerService for structured app-level logging
1818
- [x] **MatrixSdkDatabase Migration:** Migrated from deprecated HiveCollectionsDatabase to SQLite-backed MatrixSdkDatabase with automatic legacy data migration
1919
- [x] **AS Security Hardening:** Timing-safe HS token comparison (`crypto/subtle`), error detail leak removal, mandatory config validation at startup, error logging for guild operations
@@ -41,14 +41,16 @@ Architecture: **Matrix-native** (Synapse homeserver + Go Application Service + F
4141
- [x] **Leave Guild:** `room.leave()` via Matrix SDK
4242
- [x] **Invite System:** AS generates 6-char codes; `POST /invites/:code` joins space + all child rooms
4343
- [x] **Message Persistence:** `history_visibility: shared` on all rooms (no E2EE on guild rooms) so messages survive logout/login
44+
- [x] **Message History on Re-login:** `requestHistory(historyCount: 50)` called automatically when local SQLite cache is empty after re-login — general channel messages are never lost
4445
- [x] **Owner Detection:** Extracted from `m.room.create` state event `senderId`
46+
- [x] **Child Room Power Levels:** All guild child rooms (general, voice) created with `users_default: 100` and `state_default: 0` so every member can send messages, set `m.call.member` state, and create new channels without needing admin rights
4547

4648
### Channels (Matrix Rooms)
4749
- [x] **Channel List:** Text and voice rooms as space children
4850
- [x] **Create Channel:** Matrix room creation + `m.space.child` state event; default power levels allow all members to create channels
4951
- [x] **Delete Channel:** `room.leave()` via Matrix SDK
5052
- [x] **Channel Types:** Text and voice differentiation
51-
- [x] **Channels Visible After Join:** Invite-join flow auto-joins child rooms; channels appear immediately
53+
- [x] **Channels Visible After Join:** Invite-join flow auto-joins child rooms; channels appear immediately for newly joined members (power levels allow all members to read and interact)
5254

5355
### Chat (Matrix Timeline)
5456
- [x] **Real-time Messaging:** Matrix sync / timeline stream for instant delivery
@@ -68,6 +70,7 @@ Architecture: **Matrix-native** (Synapse homeserver + Go Application Service + F
6870

6971
### Presence (Matrix-native)
7072
- [x] **Online/Away/Offline:** `client.onPresenceChanged.stream``PresenceNotifier`
73+
- [x] **Eager Initialization:** `presenceProvider` is eagerly started in `ConcordApp.build()` alongside `autoStatusProvider` so no presence events from the initial Matrix sync are missed
7174
- [x] **Auto-Away (Desktop):** 5-minute idle timer (mouse/keyboard inactivity)
7275
- [x] **Auto-Away (Mobile):** 30-second background grace period
7376
- [x] **Status Indicator:** Always visible in user controls
@@ -78,6 +81,7 @@ Architecture: **Matrix-native** (Synapse homeserver + Go Application Service + F
7881
- [x] **Connect/Disconnect:** Join/leave voice rooms via LiveKit + Matrix state events
7982
- [x] **m.call.member State:** Voice membership tracked via Matrix state events with `expires_ts`
8083
- [x] **VoiceStateStoreNotifier:** Parses `m.call.member` from all rooms on each sync
84+
- [x] **Multi-User Voice Visibility:** Both users' `m.call.member` state events are correctly visible to one another — tested via integration tests (sequential and simultaneous join scenarios)
8185
- [x] **Mute/Deafen Toggles:** Local track control + `broadcastVoiceStateChange()` state update
8286
- [x] **Single-Channel Enforcement:** Client-side invariant via `VoiceController` + `_broadcastLeave()` for old channel on switch
8387
- [x] **Voice Cleanup on Logout:** `leaveChannel()` called before `client.logout()` to clear `m.call.member` state

0 commit comments

Comments
 (0)