@@ -416,3 +416,79 @@ def test_recovery_from_trapped_views_auto_migration(self):
416416 id | level
417417----+-------
418418""" )
419+
420+ class SubscribeViews (Smoketest ):
421+ MODULE_CODE = """
422+ use spacetimedb::{Identity, ReducerContext, Table, ViewContext};
423+
424+ #[derive(Copy, Clone)]
425+ #[spacetimedb::table(name = player_state)]
426+ pub struct PlayerState {
427+ #[primary_key]
428+ identity: Identity,
429+ #[unique]
430+ name: String,
431+ }
432+
433+ #[spacetimedb::view(name = my_player, public)]
434+ pub fn my_player(ctx: &ViewContext) -> Option<PlayerState> {
435+ ctx.db.player_state().identity().find(ctx.sender)
436+ }
437+
438+ #[spacetimedb::reducer]
439+ pub fn insert_player(ctx: &ReducerContext, name: String) {
440+ ctx.db.player_state().insert(PlayerState { name, identity: ctx.sender });
441+ }
442+ """
443+
444+ def assertSql (self , sql , expected ):
445+ self .maxDiff = None
446+ sql_out = self .spacetime ("sql" , self .database_identity , sql )
447+ sql_out = "\n " .join ([line .rstrip () for line in sql_out .splitlines ()])
448+ expected = "\n " .join ([line .rstrip () for line in expected .splitlines ()])
449+
450+ def test_subscribing_with_different_identities (self ):
451+ """Tests different clients subscribing to a client-specific view"""
452+
453+ # Insert an identity for Alice
454+ self .call ("insert_player" , "Alice" )
455+
456+ # Insert a new identity for Bob
457+ self .reset_config ()
458+ self .new_identity ()
459+ self .call ("insert_player" , "Bob" )
460+
461+ # Subscribe to `my_player` as Bob
462+ sub = self .subscribe ("select * from my_player" , n = 1 )
463+ events = sub ()
464+
465+ # Project out the identity field.
466+ # TODO: Eventually we should be able to do this directly in the sql.
467+ # But for now we implement it in python.
468+ projection = [
469+ {
470+ 'my_player' : {
471+ 'deletes' : [
472+ {'name' : row ['name' ]}
473+ for row in event ['my_player' ]['deletes' ]
474+ ],
475+ 'inserts' : [
476+ {'name' : row ['name' ]}
477+ for row in event ['my_player' ]['inserts' ]
478+ ],
479+ }
480+ }
481+ for event in events
482+ ]
483+
484+ self .assertEqual (
485+ [
486+ {
487+ 'my_player' : {
488+ 'deletes' : [],
489+ 'inserts' : [{'name' : 'Bob' }],
490+ }
491+ },
492+ ],
493+ projection ,
494+ )
0 commit comments