mobile bluesky app made with flutter lazurite.stormlightlabs.org/
mobile bluesky flutter
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

at ft/monetization 210 lines 7.6 kB view raw
1import 'package:atproto/com_atproto_repo_listrecords.dart'; 2import 'package:atproto_core/atproto_core.dart'; 3import 'package:flutter_test/flutter_test.dart'; 4import 'package:lazurite/features/devtools/cubit/dev_tools_cubit.dart'; 5 6void main() { 7 group('CollectionSummary', () { 8 test('countLabel shows placeholder until count is known', () { 9 expect(const CollectionSummary('app.bsky.feed.post').countLabel, '...'); 10 expect(const CollectionSummary('app.bsky.feed.post', recordCount: 12).countLabel, '12'); 11 }); 12 }); 13 14 group('RecordInfo', () { 15 test('creates with required parameters', () { 16 const record = RecordInfo( 17 uri: 'at://did:plc:test/app.bsky.feed.post/abc123', 18 cid: 'bafyrei123', 19 value: {'text': 'Hello'}, 20 ); 21 22 expect(record.uri, 'at://did:plc:test/app.bsky.feed.post/abc123'); 23 expect(record.cid, 'bafyrei123'); 24 expect(record.value, {'text': 'Hello'}); 25 }); 26 27 test('rkey extracts last path segment', () { 28 const record = RecordInfo(uri: 'at://did:plc:test/app.bsky.feed.post/abc123', value: {}); 29 expect(record.rkey, 'abc123'); 30 }); 31 32 test('rkey returns empty string for invalid URI', () { 33 const record = RecordInfo(uri: 'invalid', value: {}); 34 expect(record.rkey, ''); 35 }); 36 37 test('atUriToLink constructs aturi.to URL', () { 38 const record = RecordInfo( 39 uri: 'at://did:plc:ewvi7nxzyoun6zhxrhs64oiz/app.bsky.feed.post/3m6mwoadjbp2d', 40 value: {}, 41 ); 42 43 expect(record.atUriToLink, 'https://aturi.to/did:plc:ewvi7nxzyoun6zhxrhs64oiz/app.bsky.feed.post/3m6mwoadjbp2d'); 44 }); 45 }); 46 47 group('DevToolsState', () { 48 test('initial state has default values', () { 49 const state = DevToolsState(); 50 51 expect(state.status, DevToolsStatus.initial); 52 expect(state.did, isNull); 53 expect(state.handle, isNull); 54 expect(state.repoHandle, isNull); 55 expect(state.collections, isEmpty); 56 expect(state.isCollectionCountsLoading, isFalse); 57 expect(state.selectedCollection, isNull); 58 expect(state.records, isNull); 59 expect(state.recordsCursor, isNull); 60 expect(state.selectedRecord, isNull); 61 expect(state.isCollectionLoading, isFalse); 62 expect(state.isRecordLoading, isFalse); 63 expect(state.errorMessage, isNull); 64 }); 65 66 test('isLoading returns true for loading statuses', () { 67 expect(const DevToolsState(status: DevToolsStatus.loading).isLoading, isTrue); 68 expect(const DevToolsState(status: DevToolsStatus.loadingMore).isLoading, isTrue); 69 expect(const DevToolsState(status: DevToolsStatus.initial).isLoading, isFalse); 70 expect(const DevToolsState(status: DevToolsStatus.repoLoaded).isLoading, isFalse); 71 }); 72 73 test('isNavigating returns true for collection or record transitions', () { 74 expect(const DevToolsState(isCollectionLoading: true).isNavigating, isTrue); 75 expect(const DevToolsState(isRecordLoading: true).isNavigating, isTrue); 76 expect(const DevToolsState().isNavigating, isFalse); 77 }); 78 79 test('hasMoreRecords returns true when cursor exists', () { 80 expect(const DevToolsState(recordsCursor: 'cursor123').hasMoreRecords, isTrue); 81 expect(const DevToolsState(recordsCursor: '').hasMoreRecords, isFalse); 82 expect(const DevToolsState().hasMoreRecords, isFalse); 83 }); 84 85 test('totalRecords returns loaded records length', () { 86 final records = [ 87 const RepoListRecordsRecord( 88 uri: AtUri('at://did:plc:test/app.bsky.feed.post/1'), 89 cid: 'cid1', 90 value: {'text': 'test'}, 91 ), 92 const RepoListRecordsRecord( 93 uri: AtUri('at://did:plc:test/app.bsky.feed.post/2'), 94 cid: 'cid2', 95 value: {'text': 'test2'}, 96 ), 97 ]; 98 99 expect(DevToolsState(records: records).totalRecords, 2); 100 expect(const DevToolsState().totalRecords, 0); 101 }); 102 103 test('totalRepoRecords returns null until all counts are known', () { 104 const state = DevToolsState( 105 collections: [CollectionSummary('app.bsky.feed.post', recordCount: 2), CollectionSummary('app.bsky.feed.like')], 106 ); 107 108 expect(state.totalRepoRecords, isNull); 109 expect( 110 const DevToolsState( 111 collections: [ 112 CollectionSummary('app.bsky.feed.post', recordCount: 2), 113 CollectionSummary('app.bsky.feed.like', recordCount: 3), 114 ], 115 ).totalRepoRecords, 116 5, 117 ); 118 }); 119 120 test('copyWith preserves unspecified values', () { 121 const state = DevToolsState( 122 status: DevToolsStatus.repoLoaded, 123 did: 'did:plc:test', 124 handle: 'test.bsky.social', 125 repoHandle: 'test.bsky.social', 126 collections: [CollectionSummary('app.bsky.feed.post')], 127 ); 128 129 final copied = state.copyWith(selectedCollection: 'app.bsky.feed.post'); 130 131 expect(copied.status, DevToolsStatus.repoLoaded); 132 expect(copied.did, 'did:plc:test'); 133 expect(copied.selectedCollection, 'app.bsky.feed.post'); 134 }); 135 136 test('copyWith can clear nullable fields', () { 137 final records = [ 138 const RepoListRecordsRecord( 139 uri: AtUri('at://did:plc:test/app.bsky.feed.post/1'), 140 cid: 'cid1', 141 value: {'text': 'test'}, 142 ), 143 ]; 144 145 final state = DevToolsState( 146 status: DevToolsStatus.recordLoaded, 147 did: 'did:plc:test', 148 handle: 'test.bsky.social', 149 repoHandle: 'test.bsky.social', 150 collections: const [CollectionSummary('app.bsky.feed.post', recordCount: 1)], 151 isCollectionCountsLoading: true, 152 selectedCollection: 'app.bsky.feed.post', 153 records: records, 154 recordsCursor: 'cursor', 155 selectedRecord: const RecordInfo(uri: 'at://did:plc:test/app.bsky.feed.post/1', value: {'text': 'full'}), 156 isCollectionLoading: true, 157 isRecordLoading: true, 158 errorMessage: 'error', 159 ); 160 161 final updated = state.copyWith( 162 did: null, 163 handle: null, 164 repoHandle: null, 165 isCollectionCountsLoading: false, 166 selectedCollection: null, 167 records: null, 168 recordsCursor: null, 169 selectedRecord: null, 170 isCollectionLoading: false, 171 isRecordLoading: false, 172 errorMessage: null, 173 ); 174 175 expect(updated.did, isNull); 176 expect(updated.handle, isNull); 177 expect(updated.repoHandle, isNull); 178 expect(updated.isCollectionCountsLoading, isFalse); 179 expect(updated.selectedCollection, isNull); 180 expect(updated.records, isNull); 181 expect(updated.recordsCursor, isNull); 182 expect(updated.selectedRecord, isNull); 183 expect(updated.isCollectionLoading, isFalse); 184 expect(updated.isRecordLoading, isFalse); 185 expect(updated.errorMessage, isNull); 186 }); 187 188 test('props includes all fields for equality', () { 189 const state = DevToolsState( 190 status: DevToolsStatus.repoLoaded, 191 did: 'did:plc:test', 192 handle: 'test.bsky.social', 193 repoHandle: 'test.bsky.social', 194 collections: [CollectionSummary('app.bsky.feed.post', recordCount: 1)], 195 isCollectionCountsLoading: true, 196 selectedCollection: 'app.bsky.feed.post', 197 recordsCursor: 'cursor', 198 selectedRecord: RecordInfo(uri: 'at://test', value: {}), 199 isCollectionLoading: true, 200 isRecordLoading: true, 201 errorMessage: 'error', 202 ); 203 204 expect(state.props.length, 13); 205 expect(state.props, contains(DevToolsStatus.repoLoaded)); 206 expect(state.props, contains(true)); 207 expect(state.props, contains('did:plc:test')); 208 }); 209 }); 210}