Build Reactive Signals for Bluesky's AT Protocol Firehose in Laravel
at dev 3.9 kB view raw
1<?php 2 3namespace SocialDept\AtpSignals\Tests\Unit; 4 5use Orchestra\Testbench\TestCase; 6use SocialDept\AtpSignals\Events\CommitEvent; 7use SocialDept\AtpSignals\Events\SignalEvent; 8use SocialDept\AtpSignals\Signals\Signal; 9 10class SignalTest extends TestCase 11{ 12 /** @test */ 13 public function it_can_create_a_signal() 14 { 15 $signal = new class () extends Signal { 16 public function eventTypes(): array 17 { 18 return ['commit']; 19 } 20 21 public function handle(SignalEvent $event): void 22 { 23 // 24 } 25 }; 26 27 $this->assertInstanceOf(Signal::class, $signal); 28 $this->assertEquals(['commit'], $signal->eventTypes()); 29 } 30 31 /** @test */ 32 public function it_can_filter_by_exact_collection() 33 { 34 $signal = new class () extends Signal { 35 public function eventTypes(): array 36 { 37 return ['commit']; 38 } 39 40 public function collections(): ?array 41 { 42 return ['app.bsky.feed.post']; 43 } 44 45 public function handle(SignalEvent $event): void 46 { 47 // 48 } 49 }; 50 51 $event = new SignalEvent( 52 did: 'did:plc:test', 53 timeUs: time() * 1000000, 54 kind: 'commit', 55 commit: new CommitEvent( 56 rev: 'test', 57 operation: 'create', 58 collection: 'app.bsky.feed.post', 59 rkey: 'test', 60 ), 61 ); 62 63 $this->assertTrue($signal->shouldHandle($event)); 64 } 65 66 /** @test */ 67 public function it_can_filter_by_wildcard_collection() 68 { 69 $signalClass = new class () extends Signal { 70 public function eventTypes(): array 71 { 72 return ['commit']; 73 } 74 75 public function collections(): ?array 76 { 77 return ['app.bsky.feed.*']; 78 } 79 80 public function handle(SignalEvent $event): void 81 { 82 // 83 } 84 }; 85 86 // Create registry and register the signal 87 $registry = new \SocialDept\AtpSignals\Services\SignalRegistry(); 88 $registry->register($signalClass::class); 89 90 // Test that it matches app.bsky.feed.post 91 $postEvent = new SignalEvent( 92 did: 'did:plc:test', 93 timeUs: time() * 1000000, 94 kind: 'commit', 95 commit: new CommitEvent( 96 rev: 'test', 97 operation: 'create', 98 collection: 'app.bsky.feed.post', 99 rkey: 'test', 100 ), 101 ); 102 103 $matchingSignals = $registry->getMatchingSignals($postEvent); 104 $this->assertCount(1, $matchingSignals); 105 106 // Test that it matches app.bsky.feed.like 107 $likeEvent = new SignalEvent( 108 did: 'did:plc:test', 109 timeUs: time() * 1000000, 110 kind: 'commit', 111 commit: new CommitEvent( 112 rev: 'test', 113 operation: 'create', 114 collection: 'app.bsky.feed.like', 115 rkey: 'test', 116 ), 117 ); 118 119 $matchingSignals = $registry->getMatchingSignals($likeEvent); 120 $this->assertCount(1, $matchingSignals); 121 122 // Test that it does NOT match app.bsky.graph.follow 123 $followEvent = new SignalEvent( 124 did: 'did:plc:test', 125 timeUs: time() * 1000000, 126 kind: 'commit', 127 commit: new CommitEvent( 128 rev: 'test', 129 operation: 'create', 130 collection: 'app.bsky.graph.follow', 131 rkey: 'test', 132 ), 133 ); 134 135 $matchingSignals = $registry->getMatchingSignals($followEvent); 136 $this->assertCount(0, $matchingSignals); 137 } 138}