Add status route tests, OG images blog post, and blog tests
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 9m27s
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 9m27s
- Create src/routes/__tests__/status.test.ts (GET /status and /status.html) - Add blog post: public/blog/automating-og-images.html (~1000 words) - Update public/blog.html with new post entry - Update public/sitemap.xml with new URL - Add blog tests for automating-og-images post - Update existing blog tests for new post references Tests: 332 passed, 1 skipped
This commit is contained in:
parent
05c91e6747
commit
740c70f905
5 changed files with 378 additions and 1 deletions
|
|
@ -51,11 +51,12 @@ describe('Blog Index Page', () => {
|
|||
expect(html).toContain('"@type":"Blog"')
|
||||
})
|
||||
|
||||
it('links to both blog posts', async () => {
|
||||
it('links to all blog posts', async () => {
|
||||
const res = await request(app).get('/blog.html')
|
||||
const html = res.text
|
||||
expect(html).toContain('/blog/why-screenshot-api')
|
||||
expect(html).toContain('/blog/screenshot-api-performance')
|
||||
expect(html).toContain('/blog/automating-og-images')
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -153,12 +154,60 @@ describe('Blog Post: Screenshot API Performance', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('Blog Post: Automating OG Images', () => {
|
||||
const app = createApp()
|
||||
|
||||
it('GET /blog/automating-og-images.html returns 200', async () => {
|
||||
const res = await request(app).get('/blog/automating-og-images.html')
|
||||
expect(res.status).toBe(200)
|
||||
expect(res.headers['content-type']).toContain('text/html')
|
||||
})
|
||||
|
||||
it('GET /blog/automating-og-images redirects 301 to .html', async () => {
|
||||
const res = await request(app).get('/blog/automating-og-images')
|
||||
expect(res.status).toBe(301)
|
||||
expect(res.headers.location).toBe('/blog/automating-og-images.html')
|
||||
})
|
||||
|
||||
it('contains required SEO elements', async () => {
|
||||
const res = await request(app).get('/blog/automating-og-images.html')
|
||||
const html = res.text
|
||||
expect(html).toMatch(/<title>.+<\/title>/)
|
||||
expect(html).toMatch(/<meta name="description" content=".+"/)
|
||||
expect(html).toMatch(/<meta property="og:title"/)
|
||||
expect(html).toMatch(/<meta property="og:description"/)
|
||||
expect(html).toMatch(/<link rel="canonical" href="https:\/\/snapapi\.eu\/blog\/automating-og-images"/)
|
||||
expect(html).toMatch(/<meta name="twitter:card"/)
|
||||
})
|
||||
|
||||
it('contains JSON-LD BlogPosting schema', async () => {
|
||||
const res = await request(app).get('/blog/automating-og-images.html')
|
||||
const html = res.text
|
||||
expect(html).toContain('"@type":"BlogPosting"')
|
||||
})
|
||||
|
||||
it('has substantial content (~800 words)', async () => {
|
||||
const res = await request(app).get('/blog/automating-og-images.html')
|
||||
const text = res.text.replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ')
|
||||
const wordCount = text.split(' ').filter(w => w.length > 0).length
|
||||
expect(wordCount).toBeGreaterThan(600)
|
||||
})
|
||||
|
||||
it('contains relevant keywords', async () => {
|
||||
const res = await request(app).get('/blog/automating-og-images.html')
|
||||
const html = res.text
|
||||
expect(html).toContain('OG image')
|
||||
expect(html).toContain('screenshot API')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Blog Sitemap & Navigation', () => {
|
||||
it('sitemap contains blog URLs', () => {
|
||||
const sitemap = fs.readFileSync(path.join(publicDir, 'sitemap.xml'), 'utf-8')
|
||||
expect(sitemap).toContain('https://snapapi.eu/blog')
|
||||
expect(sitemap).toContain('https://snapapi.eu/blog/why-screenshot-api')
|
||||
expect(sitemap).toContain('https://snapapi.eu/blog/screenshot-api-performance')
|
||||
expect(sitemap).toContain('https://snapapi.eu/blog/automating-og-images')
|
||||
})
|
||||
|
||||
it('index.html has Blog link in nav or footer', () => {
|
||||
|
|
|
|||
36
src/routes/__tests__/status.test.ts
Normal file
36
src/routes/__tests__/status.test.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import { describe, it, expect } from 'vitest'
|
||||
import request from 'supertest'
|
||||
import express from 'express'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const publicDir = path.join(__dirname, '../../../public')
|
||||
|
||||
function createApp() {
|
||||
const app = express()
|
||||
app.use(express.static(publicDir, { etag: true }))
|
||||
|
||||
// Mirror the status route from index.ts
|
||||
app.get('/status', (_req, res) => {
|
||||
res.sendFile(path.join(publicDir, 'status.html'))
|
||||
})
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
describe('Status Route', () => {
|
||||
const app = createApp()
|
||||
|
||||
it('GET /status returns 200', async () => {
|
||||
const res = await request(app).get('/status')
|
||||
expect(res.status).toBe(200)
|
||||
expect(res.headers['content-type']).toContain('text/html')
|
||||
})
|
||||
|
||||
it('GET /status.html returns 200', async () => {
|
||||
const res = await request(app).get('/status.html')
|
||||
expect(res.status).toBe(200)
|
||||
expect(res.headers['content-type']).toContain('text/html')
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue