Barazo AppView backend barazo.forum
at main 201 lines 6.3 kB view raw
1import { describe, it, expect } from 'vitest' 2import { 3 createModNoteSchema, 4 modNoteQuerySchema, 5 createTopicNoticeSchema, 6 // dismissTopicNoticeSchema and topicNoticeQuerySchema tested via route-level integration 7 createWarningSchema, 8 warningQuerySchema, 9 acknowledgeWarningSchema, 10} from '../../../src/validation/mod-annotations.js' 11 12describe('mod annotation validation schemas', () => { 13 describe('createModNoteSchema', () => { 14 it('should accept valid user note', () => { 15 const result = createModNoteSchema.safeParse({ 16 subjectDid: 'did:plc:abc123', 17 content: 'User was warned verbally in chat.', 18 }) 19 expect(result.success).toBe(true) 20 }) 21 22 it('should accept valid post note', () => { 23 const result = createModNoteSchema.safeParse({ 24 subjectUri: 'at://did:plc:abc/forum.barazo.topic.post/123', 25 content: 'Borderline post, left up after review.', 26 }) 27 expect(result.success).toBe(true) 28 }) 29 30 it('should reject note with both subjectDid and subjectUri', () => { 31 const result = createModNoteSchema.safeParse({ 32 subjectDid: 'did:plc:abc123', 33 subjectUri: 'at://did:plc:abc/forum.barazo.topic.post/123', 34 content: 'Invalid.', 35 }) 36 expect(result.success).toBe(false) 37 }) 38 39 it('should reject note with neither subjectDid nor subjectUri', () => { 40 const result = createModNoteSchema.safeParse({ 41 content: 'No subject.', 42 }) 43 expect(result.success).toBe(false) 44 }) 45 46 it('should reject empty content', () => { 47 const result = createModNoteSchema.safeParse({ 48 subjectDid: 'did:plc:abc123', 49 content: '', 50 }) 51 expect(result.success).toBe(false) 52 }) 53 54 it('should reject content over 5000 chars', () => { 55 const result = createModNoteSchema.safeParse({ 56 subjectDid: 'did:plc:abc123', 57 content: 'a'.repeat(5001), 58 }) 59 expect(result.success).toBe(false) 60 }) 61 }) 62 63 describe('modNoteQuerySchema', () => { 64 it('should accept valid query with subjectDid', () => { 65 const result = modNoteQuerySchema.safeParse({ 66 subjectDid: 'did:plc:abc123', 67 }) 68 expect(result.success).toBe(true) 69 }) 70 71 it('should accept valid query with subjectUri', () => { 72 const result = modNoteQuerySchema.safeParse({ 73 subjectUri: 'at://did:plc:abc/forum.barazo.topic.post/123', 74 }) 75 expect(result.success).toBe(true) 76 }) 77 78 it('should accept query with cursor and limit', () => { 79 const result = modNoteQuerySchema.safeParse({ 80 subjectDid: 'did:plc:abc123', 81 cursor: '10', 82 limit: 50, 83 }) 84 expect(result.success).toBe(true) 85 }) 86 87 it('should default limit to 25', () => { 88 const result = modNoteQuerySchema.safeParse({ 89 subjectDid: 'did:plc:abc123', 90 }) 91 expect(result.success).toBe(true) 92 if (result.success) { 93 expect(result.data.limit).toBe(25) 94 } 95 }) 96 }) 97 98 describe('createTopicNoticeSchema', () => { 99 it('should accept valid notice', () => { 100 const result = createTopicNoticeSchema.safeParse({ 101 topicUri: 'at://did:plc:abc/forum.barazo.topic.post/123', 102 noticeType: 'closed', 103 headline: 'This topic has been closed.', 104 }) 105 expect(result.success).toBe(true) 106 }) 107 108 it('should accept notice with optional body', () => { 109 const result = createTopicNoticeSchema.safeParse({ 110 topicUri: 'at://did:plc:abc/forum.barazo.topic.post/123', 111 noticeType: 'custom', 112 headline: 'Please read before posting.', 113 body: 'This topic has specific rules.', 114 }) 115 expect(result.success).toBe(true) 116 }) 117 118 it('should reject headline over 200 chars', () => { 119 const result = createTopicNoticeSchema.safeParse({ 120 topicUri: 'at://did:plc:abc/forum.barazo.topic.post/123', 121 noticeType: 'closed', 122 headline: 'a'.repeat(201), 123 }) 124 expect(result.success).toBe(false) 125 }) 126 127 it('should reject invalid notice type', () => { 128 const result = createTopicNoticeSchema.safeParse({ 129 topicUri: 'at://did:plc:abc/forum.barazo.topic.post/123', 130 noticeType: 'invalid', 131 headline: 'Test.', 132 }) 133 expect(result.success).toBe(false) 134 }) 135 }) 136 137 describe('createWarningSchema', () => { 138 it('should accept valid warning', () => { 139 const result = createWarningSchema.safeParse({ 140 targetDid: 'did:plc:user123', 141 warningType: 'rule_violation', 142 message: 'Your post violated community rule #3.', 143 }) 144 expect(result.success).toBe(true) 145 }) 146 147 it('should accept warning with optional fields', () => { 148 const result = createWarningSchema.safeParse({ 149 targetDid: 'did:plc:user123', 150 warningType: 'harassment', 151 message: 'Please review our community guidelines.', 152 modComment: 'This is a first offense.', 153 internalNote: 'User has been argumentative in multiple threads.', 154 }) 155 expect(result.success).toBe(true) 156 }) 157 158 it('should reject modComment over 300 chars', () => { 159 const result = createWarningSchema.safeParse({ 160 targetDid: 'did:plc:user123', 161 warningType: 'other', 162 message: 'Warning.', 163 modComment: 'a'.repeat(301), 164 }) 165 expect(result.success).toBe(false) 166 }) 167 168 it('should reject empty message', () => { 169 const result = createWarningSchema.safeParse({ 170 targetDid: 'did:plc:user123', 171 warningType: 'other', 172 message: '', 173 }) 174 expect(result.success).toBe(false) 175 }) 176 }) 177 178 describe('acknowledgeWarningSchema', () => { 179 it('should accept valid warning id param', () => { 180 const result = acknowledgeWarningSchema.safeParse({ id: '5' }) 181 expect(result.success).toBe(true) 182 }) 183 }) 184 185 describe('warningQuerySchema', () => { 186 it('should accept query with targetDid', () => { 187 const result = warningQuerySchema.safeParse({ 188 targetDid: 'did:plc:user123', 189 }) 190 expect(result.success).toBe(true) 191 }) 192 193 it('should default limit to 25', () => { 194 const result = warningQuerySchema.safeParse({}) 195 expect(result.success).toBe(true) 196 if (result.success) { 197 expect(result.data.limit).toBe(25) 198 } 199 }) 200 }) 201})