storipress/karbon

View on GitHub
packages/karbon/src/runtime/composables/__tests__/seo-preset.spec.ts

Summary

Maintainability
F
4 days
Test Coverage
import { expect, it } from 'vitest'
import { identity, reduce } from 'remeda'
import { htmlFilter } from '@storipress/karbon-utils'
import type { SEOContext } from '../seo-preset'
import { resolveSEOPresets } from '../seo-preset'
import type { BaseMeta, ResourcePage } from '../../types'

it('can handle article', () => {
  const handlers = resolveSEOPresets([{ preset: 'basic' }])
  const results: unknown[] = []
  const resourceURL: ResourcePage<BaseMeta> = {
    enable: true,
    isValid: () => true,
    getIdentity: () => ({ type: 'article', id: '1' }),
    toURL: () => '',
    route: '',
  }
  const context: SEOContext = {
    metaType: 'article',
    runtimeConfig: {} as any,
    site: {
      name: 'site_name',
    },
    articleFilter: identity,
    useHead: (input: unknown) => void results.push(input),
    useSeoMeta: (input: unknown) => void results.push(input),
    resourceUrls: {
      article: {
        ...resourceURL,
        toURL: () => 'article_url',
      },
      desk: {
        ...resourceURL,
        toURL: () => 'desk_url',
      },
      author: {
        ...resourceURL,
        toURL: () => 'author_url',
      },
      tag: {
        ...resourceURL,
        toURL: () => 'tag_url',
      },
    },
  }

  const article = {
    title: 'title',
    blurb: 'blurb',
    bio: 'author_bio',
    cover: {
      url: 'cover_url',
    },
    author: {
      name: 'author_name',
    },
  }

  for (const handler of handlers) {
    handler(article, context)
  }

  expect(reduce(results, (acc, cur) => Object.assign(acc, cur), {})).toMatchSnapshot()
})

it('can handle article with html', () => {
  const handlers = resolveSEOPresets([{ preset: 'basic' }])
  const results: unknown[] = []
  const resourceURL: ResourcePage<BaseMeta> = {
    enable: true,
    isValid: () => true,
    getIdentity: () => ({ type: 'article', id: '1' }),
    toURL: () => '',
    route: '',
  }
  const context: SEOContext = {
    metaType: 'article',
    runtimeConfig: {} as any,
    site: {
      name: 'site_name',
    },
    articleFilter: htmlFilter,
    useHead: (input: unknown) => void results.push(input),
    useSeoMeta: (input: unknown) => void results.push(input),
    resourceUrls: {
      article: {
        ...resourceURL,
        toURL: () => 'article_url',
      },
      desk: {
        ...resourceURL,
        toURL: () => 'desk_url',
      },
      author: {
        ...resourceURL,
        toURL: () => 'author_url',
      },
      tag: {
        ...resourceURL,
        toURL: () => 'tag_url',
      },
    },
  }

  const article = {
    title: '<p>title</p>',
    blurb: 'blurb',
    bio: 'author_bio',
    seo: {
      og: {
        title: '',
        description: '',
      },
      meta: {
        title: '',
        description: '',
      },
      hasSlug: false,
      ogImage: '',
    },
    cover: {
      url: 'cover_url',
    },
    author: {
      name: 'author_name',
    },
  }

  for (const handler of handlers) {
    handler(article, context)
  }

  expect(reduce(results, (acc, cur) => Object.assign(acc, cur), {})).toMatchSnapshot()
})

const ARTICLE_FIXTURE = {
  __typename: 'Article',
  slug: 'article_slug',
  featured: false,
  layout: null,
  shadow_authors: null,
  metafields: [],
  relevances: [
    {
      __typename: 'Article',
      id: '2',
      title: '<p>Another Article</p>',
    },
  ],
  content_blocks: [],
  bio: 'My bio',
  bioHTML: '<p>My bio</p>',
  published_at: '2024-01-01T00:00:00+00:00',
  updated_at: '2024-01-01T00:00:00+00:00',
  title: '<p>title</p>',
  blurb: '<p>blurb</p>',
  seo: {
    og: {
      title: 'og_title',
      description: 'og_description',
    },
    meta: {
      title: 'meta_title',
      description: 'meta_description',
    },
    hasSlug: true,
    ogImage: '',
  },
  plaintext: 'Hello world',
  cover: {
    alt: 'cover alt',
    url: 'https://example.com/cover.png',
    crop: {
      key: '123',
      top: 50,
      left: 50,
      zoom: 1,
      width: 0,
      height: 0,
      realWidth: 1600,
      realHeight: 915,
    },
    caption: '',
  },
  authors: [
    {
      __typename: 'User',
      bio: '<p>My bio</p>',
      slug: 'author_slug',
      avatar: 'https://example.com/profile.png',
      email: 'author@example.com',
      location: 'Earth',
      first_name: 'Author',
      last_name: 'Name',
      full_name: 'Author Name',
      id: '1',
      socials: {
        LinkedIn: 'www.example.com',
      },
      name: 'Author Name',
    },
  ],
  desk: {
    __typename: 'Desk',
    id: '5',
    name: 'Desk',
    slug: 'desk',
    layout: null,
    desk: null,
  },
  tags: [],
  id: '1',
  plan: 'free',
  html: '<p>Hello world</p>',
  segments: [
    {
      id: 'normal',
      type: 'p',
      html: '<p>Hello world</p>',
    },
  ],
  __sp_cf: {},
  __sp_cf_editor_block: {},
}

it('can handle real article', () => {
  const handlers = resolveSEOPresets([{ preset: 'basic' }])
  const results: unknown[] = []
  const resourceURL: ResourcePage<BaseMeta> = {
    enable: true,
    isValid: () => true,
    getIdentity: () => ({ type: 'article', id: '1' }),
    toURL: () => '',
    route: '',
  }
  const context: SEOContext = {
    metaType: 'article',
    runtimeConfig: {} as any,
    site: {
      name: 'site_name',
    },
    articleFilter: identity,
    useHead: (input: unknown) => void results.push(input),
    useSeoMeta: (input: unknown) => void results.push(input),
    resourceUrls: {
      article: {
        ...resourceURL,
        toURL: () => 'article_url',
      },
      desk: {
        ...resourceURL,
        toURL: () => 'desk_url',
      },
      author: {
        ...resourceURL,
        toURL: () => 'author_url',
      },
      tag: {
        ...resourceURL,
        toURL: () => 'tag_url',
      },
    },
  }

  for (const handler of handlers) {
    handler(ARTICLE_FIXTURE, context)
  }

  expect(reduce(results, (acc, cur) => Object.assign(acc, cur), {})).toMatchSnapshot()
})

const USER_FIXTURE = {
  __typename: 'User',
  id: '16',
  slug: 'user_slug',
  email: 'user@example.com',
  first_name: 'User',
  last_name: 'Name',
  full_name: 'User Name',
  avatar: 'https://example.com/profile.png',
  location: 'Earth',
  bio: '<p>Hello world</p>',
  website: 'example.com',
  socials: {
    Twitter: 'twitter.example.com',
    Facebook: 'fb.example.com',
    LinkedIn: 'linkedin.example.com',
    YouTube: 'www.youtube.com/example',
    Pinterest: 'www.example.com/a',
  },
  created_at: '2024-01-01T00:00:00+00:00',
  updated_at: '2024-01-01T00:00:00+00:00',
  desks: [],
  name: 'User Name',
  __sp_cf: {},
  __sp_cf_editor_block: {},
}

it('can handle author page', () => {
  const handlers = resolveSEOPresets([{ preset: 'basic' }])
  const results: unknown[] = []
  const resourceURL: ResourcePage<BaseMeta> = {
    enable: true,
    isValid: () => true,
    getIdentity: () => ({ type: 'article', id: '1' }),
    toURL: () => '',
    route: '',
  }
  const context: SEOContext = {
    metaType: 'author',
    runtimeConfig: {} as any,
    site: {
      name: 'site_name',
    },
    articleFilter: identity,
    useHead: (input: unknown) => void results.push(input),
    useSeoMeta: (input: unknown) => void results.push(input),
    resourceUrls: {
      article: {
        ...resourceURL,
        toURL: () => 'article_url',
      },
      desk: {
        ...resourceURL,
        toURL: () => 'desk_url',
      },
      author: {
        ...resourceURL,
        toURL: () => 'author_url',
      },
      tag: {
        ...resourceURL,
        toURL: () => 'tag_url',
      },
    },
  }

  for (const handler of handlers) {
    handler(USER_FIXTURE, context)
  }

  expect(reduce(results, (acc, cur) => Object.assign(acc, cur), {})).toMatchSnapshot()
})