import { describe, expect, it } from 'vitest' import { ORGANIZATION_ID, WEBSITE_ID, eventSchema, faqPage, organizationSchema, webSiteSchema } from '@/lib/seo/JsonLd' const eventSchemaBase = { name: 'رویداد نمونه', description: null, startDate: '2026-08-01T10:00:00Z', endDate: '2026-08-01T12:00:00Z', url: 'https://ghabilee.ir/e/sample', isFree: false, price: 250_000, } describe('SEO structured data', () => { it('converts stored toman prices to rial for IRR offers', () => { const schema = eventSchema({ ...eventSchemaBase, address: 'خیابان ولیعصر', cityName: 'تهران', }) expect(schema.offers).toMatchObject({ price: 2_500_000, priceCurrency: 'IRR' }) expect(schema).toMatchObject({ url: eventSchemaBase.url }) }) it('emits PostalAddress for a public street address', () => { const schema = eventSchema({ ...eventSchemaBase, address: 'خیابان ولیعصر، پلاک ۱۲', cityName: 'تهران', }) expect(schema.location).toEqual({ '@type': 'Place', name: 'تهران', address: { '@type': 'PostalAddress', streetAddress: 'خیابان ولیعصر، پلاک ۱۲', addressLocality: 'تهران', addressCountry: 'IR', }, }) }) it('uses generalArea when the exact address is hidden from crawlers', () => { const schema = eventSchema({ ...eventSchemaBase, address: null, generalArea: 'خیابان هفت‌تیر', cityName: 'مشهد', }) expect(schema.location.address).toEqual({ '@type': 'PostalAddress', streetAddress: 'خیابان هفت‌تیر', addressLocality: 'مشهد', addressCountry: 'IR', }) expect(JSON.stringify(schema.location)).not.toContain('null') }) it('still emits addressLocality when only the city is public', () => { const schema = eventSchema({ ...eventSchemaBase, address: null, cityName: 'اصفهان', }) expect(schema.location.address).toEqual({ '@type': 'PostalAddress', addressLocality: 'اصفهان', addressCountry: 'IR', }) }) it('treats blank address strings as missing and does not leak them', () => { const schema = eventSchema({ ...eventSchemaBase, address: ' ', generalArea: 'محدوده ونک', cityName: 'تهران', }) expect(schema.location.address.streetAddress).toBe('محدوده ونک') }) it('emits FAQPage entities for evergreen landing content', () => { const schema = faqPage([{ question: 'چطور ثبت‌نام کنم؟', answer: 'از صفحه رویداد.' }]) expect(schema).toMatchObject({ '@type': 'FAQPage', mainEntity: [{ '@type': 'Question', name: 'چطور ثبت‌نام کنم؟' }], }) }) it('uses stable IDs to connect the website and its organization', () => { const organization = organizationSchema({ url: 'https://ghabilee.ir', logo: 'https://ghabilee.ir/logo.svg', telephone: '+985100000000', address: { locality: 'مشهد', streetAddress: 'نمونه' }, }) expect(organization).toMatchObject({ '@id': ORGANIZATION_ID, alternateName: 'Ghabilee', sameAs: ['https://www.instagram.com/Ghabilee_support/', 'https://t.me/Ghabilee_support'], contactPoint: { '@type': 'ContactPoint', telephone: '+985100000000', contactType: 'customer support', areaServed: 'IR', }, }) expect(webSiteSchema('https://ghabilee.ir')).toMatchObject({ '@id': WEBSITE_ID, publisher: { '@id': ORGANIZATION_ID }, }) }) })