mirror of
https://github.com/kremalicious/blog.git
synced 2024-12-22 01:03:37 +01:00
more unit tests
This commit is contained in:
parent
8002dc0172
commit
a9f5ea925d
@ -6,6 +6,7 @@ import Search from './Search'
|
||||
let portalRoot: HTMLDivElement
|
||||
let unsubscribe: () => void
|
||||
let fetchSpy: any
|
||||
let originalFetch: any
|
||||
let storeState = false
|
||||
|
||||
beforeEach(() => {
|
||||
@ -19,6 +20,7 @@ beforeEach(() => {
|
||||
})
|
||||
|
||||
// Mock fetch API
|
||||
originalFetch = globalThis.fetch
|
||||
globalThis.fetch = async () => {
|
||||
return {
|
||||
json: () =>
|
||||
@ -30,9 +32,9 @@ beforeEach(() => {
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
// Cleanup
|
||||
portalRoot.remove()
|
||||
unsubscribe()
|
||||
globalThis.fetch = originalFetch
|
||||
})
|
||||
|
||||
test('Search component', async () => {
|
||||
|
45
src/lib/astro/getAllPosts.test.ts
Normal file
45
src/lib/astro/getAllPosts.test.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { test, expect, vi, describe, beforeEach, afterEach } from 'vitest'
|
||||
import * as loadAndFormatCollectionModule from './loadAndFormatCollection'
|
||||
import { getAllPosts } from './getAllPosts'
|
||||
import mockArticles from '@test/__fixtures__/getCollectionArticles.json'
|
||||
import mockLinks from '@test/__fixtures__/getCollectionLinks.json'
|
||||
import mockPhotos from '@test/__fixtures__/getCollectionPhotos.json'
|
||||
|
||||
let loadAndFormatCollectionSpy: any
|
||||
|
||||
beforeEach(() => {
|
||||
loadAndFormatCollectionSpy = vi.spyOn(
|
||||
loadAndFormatCollectionModule,
|
||||
'loadAndFormatCollection'
|
||||
)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
loadAndFormatCollectionSpy.mockRestore()
|
||||
})
|
||||
|
||||
describe('getAllPosts', () => {
|
||||
test('combines and sorts all posts', async () => {
|
||||
loadAndFormatCollectionSpy.mockImplementation(
|
||||
async (collectionName: string) => {
|
||||
switch (collectionName) {
|
||||
case 'articles':
|
||||
return mockArticles
|
||||
case 'links':
|
||||
return mockLinks
|
||||
case 'photos':
|
||||
return mockPhotos
|
||||
default:
|
||||
return []
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const result = await getAllPosts()
|
||||
|
||||
expect(result).toBeDefined()
|
||||
expect(result.length).toBe(
|
||||
mockArticles.length + mockLinks.length + mockPhotos.length
|
||||
)
|
||||
})
|
||||
})
|
@ -22,7 +22,6 @@ test('sortPosts sorts posts by date in descending order', () => {
|
||||
|
||||
getAllPostsSpy.mockImplementationOnce(() => Promise.resolve(posts))
|
||||
|
||||
// getAllPostsSpy = vi.spyOn(getAllPosts, async () => posts)
|
||||
const sortedPosts = sortPosts(posts)
|
||||
expect(sortedPosts[0].data.date).toStrictEqual('2022-01-03')
|
||||
expect(sortedPosts[1].data.date).toStrictEqual('2022-01-02')
|
81
src/lib/astro/loadAndFormatCollection.test.ts
Normal file
81
src/lib/astro/loadAndFormatCollection.test.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import { test, expect, vi, beforeEach, afterEach, describe } from 'vitest'
|
||||
import * as astroContent from 'astro:content'
|
||||
import * as exifLib from '@lib/exif'
|
||||
import { loadAndFormatCollection } from './loadAndFormatCollection'
|
||||
import getCollectionArticles from '@test/__fixtures__/getCollectionArticles.json'
|
||||
import getCollectionLinks from '@test/__fixtures__/getCollectionLinks.json'
|
||||
import getCollectionPhotos from '@test/__fixtures__/getCollectionPhotos.json'
|
||||
|
||||
let getCollectionSpy: any
|
||||
let readOutExifSpy: any
|
||||
|
||||
beforeEach(() => {
|
||||
getCollectionSpy = vi.spyOn(astroContent, 'getCollection')
|
||||
|
||||
readOutExifSpy = vi.spyOn(exifLib, 'readOutExif')
|
||||
readOutExifSpy.mockImplementationOnce(async () => ({
|
||||
exif: 'mocked exif',
|
||||
iptc: 'mocked iptc'
|
||||
}))
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
getCollectionSpy.mockRestore()
|
||||
readOutExifSpy.mockRestore()
|
||||
})
|
||||
|
||||
describe('loadAndFormatCollection', () => {
|
||||
test('loads articles', async () => {
|
||||
getCollectionSpy.mockImplementationOnce(async () => getCollectionArticles)
|
||||
const result = await loadAndFormatCollection('articles')
|
||||
expect(result).toBeDefined()
|
||||
expect(result.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
test('loads links', async () => {
|
||||
getCollectionSpy.mockImplementationOnce(async () => getCollectionLinks)
|
||||
const result = await loadAndFormatCollection('links')
|
||||
expect(result).toBeDefined()
|
||||
expect(result.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
test('loads photos', async () => {
|
||||
getCollectionSpy.mockImplementationOnce(async () => getCollectionPhotos)
|
||||
const result = await loadAndFormatCollection('photos')
|
||||
expect(result).toBeDefined()
|
||||
expect(result.length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
test('loads photos in production', async () => {
|
||||
const originalEnv = import.meta.env.PROD
|
||||
import.meta.env.PROD = true
|
||||
|
||||
getCollectionSpy.mockImplementationOnce(async () => getCollectionPhotos)
|
||||
const result = await loadAndFormatCollection('photos')
|
||||
expect(result).toBeDefined()
|
||||
expect(result.length).toBeGreaterThan(0)
|
||||
|
||||
import.meta.env.PROD = originalEnv
|
||||
})
|
||||
|
||||
test('filters out drafts in production', async () => {
|
||||
const originalEnv = import.meta.env.PROD
|
||||
import.meta.env.PROD = true
|
||||
|
||||
const mockDrafts = [
|
||||
{ id: '/what/an/id/and/la', data: { draft: true }, otherFields: '...' },
|
||||
{ id: '/what/an/id/and/le', data: { draft: false }, otherFields: '...' },
|
||||
{ id: '/what/an/id/and/lu', data: { draft: true }, otherFields: '...' }
|
||||
] as any
|
||||
|
||||
getCollectionSpy.mockImplementationOnce(async () => mockDrafts)
|
||||
const result = await loadAndFormatCollection('articles')
|
||||
expect(result).toBeDefined()
|
||||
// Only one article should remain after filtering out drafts
|
||||
expect(result.length).toBe(1)
|
||||
// The remaining article should not be a draft
|
||||
expect(result[0].data.draft).toBe(false)
|
||||
|
||||
import.meta.env.PROD = originalEnv
|
||||
})
|
||||
})
|
61
test/__fixtures__/getCollectionArticles.json
Normal file
61
test/__fixtures__/getCollectionArticles.json
Normal file
File diff suppressed because one or more lines are too long
28
test/__fixtures__/getCollectionLinks.json
Normal file
28
test/__fixtures__/getCollectionLinks.json
Normal file
@ -0,0 +1,28 @@
|
||||
[
|
||||
{
|
||||
"id": "2013-11-20-why-we-are-allowed-to-hate-silicon-valley.md",
|
||||
"slug": "2013-11-20-why-we-are-allowed-to-hate-silicon-valley",
|
||||
"body": "\nDon't fully agree with Evgeny Morozov's culture pessimism but he makes some good points in this article:\n\n> It might even help bury some of the myths spun by Silicon Valley. Wouldn’t it be nice if one day, told that Google’s mission is to “organize the world’s information and make it universally accessible and useful,” we would finally read between the lines and discover its true meaning: “to monetize all of the world’s information and make it universally inaccessible and profitable”? With this act of subversive interpretation, we might eventually hit upon the greatest emancipatory insight of all: Letting Google organize all of the world’s information makes as much sense as letting Halliburton organize all of the world’s oil.\n",
|
||||
"collection": "links",
|
||||
"data": {
|
||||
"title": "Why We Are Allowed to Hate Silicon Valley",
|
||||
"tags": ["silicon valley", "google"],
|
||||
"linkurl": "http://www.faz.net/aktuell/feuilleton/debatten/the-internet-ideology-why-we-are-allowed-to-hate-silicon-valley-12658406.html",
|
||||
"date": "2013-11-20T00:00:00.000Z",
|
||||
"githubLink": "https://github.com/kremalicious/blog/tree/main/content/links/2013-11-20-why-we-are-allowed-to-hate-silicon-valley.md"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2013-12-11-silicon-valley-isnt-a-meritocracy.md",
|
||||
"slug": "2013-12-11-silicon-valley-isnt-a-meritocracy",
|
||||
"body": "\nFrom [Silicon Valley Isn't a Meritocracy — And It's Dangerous to Hero-Worship Entrepreneurs](http://www.wired.com/opinion/2013/11/silicon-valley-isnt-a-meritocracy-and-the-cult-of-the-entrepreneur-holds-people-back/):\n\n> People in tech repeatedly portray Silicon Valley as places where the smartest, most motivated people from around the globe are changing the world for the better, and this rhetoric has been taken up and repeated often by traditional media outlets. Unlike, say, community activists, public schoolteachers, social workers, or health care providers, technologists are ultimately focused on a small slice of the population, and they are primarily looking for ideas that will prove profitable. These entrepreneurs may have a passion for better audio streaming or e-mail, but to say that such pursuits are world-changing is a bit disingenuous.\n",
|
||||
"collection": "links",
|
||||
"data": {
|
||||
"title": "Silicon Valley Isn't a Meritocracy",
|
||||
"tags": ["silicon valley"],
|
||||
"linkurl": "https://www.wired.com/2013/11/silicon-valley-isnt-a-meritocracy-and-the-cult-of-the-entrepreneur-holds-people-back/",
|
||||
"date": "2013-12-11T00:00:00.000Z",
|
||||
"githubLink": "https://github.com/kremalicious/blog/tree/main/content/links/2013-12-11-silicon-valley-isnt-a-meritocracy.md"
|
||||
}
|
||||
}
|
||||
]
|
70
test/__fixtures__/getCollectionPhotos.json
Normal file
70
test/__fixtures__/getCollectionPhotos.json
Normal file
@ -0,0 +1,70 @@
|
||||
[
|
||||
{
|
||||
"id": "2021-11-21-assembleia-da-republica/index.md",
|
||||
"slug": "2021-11-21-assembleia-da-republica",
|
||||
"body": "\nIn front of the [Palácio de São Bento](https://en.wikipedia.org/wiki/São_Bento_Palace) housing the [Portuguese parliament](<https://en.wikipedia.org/wiki/Assembly_of_the_Republic_(Portugal)>) in Lisbon, Portugal.\n",
|
||||
"collection": "photos",
|
||||
"data": {
|
||||
"title": "Assembleia da República",
|
||||
"date": "2021-11-21T17:08:39.000Z",
|
||||
"image": {
|
||||
"src": "/@fs/Users/m/Code/blog/src/content/photos/2021-11-21-assembleia-da-republica/2021-11-21-assembleia-da-republica.jpg?origWidth=2393&origHeight=3181&origFormat=jpg",
|
||||
"width": 2393,
|
||||
"height": 3181,
|
||||
"format": "jpg",
|
||||
"orientation": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2021-11-25-praca-do-comercio/index.md",
|
||||
"slug": "2021-11-25-praca-do-comercio",
|
||||
"body": "\nOn the [Praça do Comércio](https://en.wikipedia.org/wiki/Praça_do_Comércio) looking at the [Arco da Rua Augusta](https://en.wikipedia.org/wiki/Rua_Augusta_Arch) surrounded by the usual spectacular light in Lisbon, Portugal.\n",
|
||||
"collection": "photos",
|
||||
"data": {
|
||||
"title": "Praça do Comércio",
|
||||
"date": "2021-11-25T16:59:58.000Z",
|
||||
"image": {
|
||||
"src": "/@fs/Users/m/Code/blog/src/content/photos/2021-11-25-praca-do-comercio/2021-11-25-praca-do-comercio.jpg?origWidth=2735&origHeight=3646&origFormat=jpg",
|
||||
"width": 2735,
|
||||
"height": 3646,
|
||||
"format": "jpg",
|
||||
"orientation": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2021-11-26-forever-bicycles/index.md",
|
||||
"slug": "2021-11-26-forever-bicycles",
|
||||
"body": "\nAi Weiwei's installation [Forever Bicycles from 2015](https://artsandculture.google.com/asset/forever-bicycle/XAFbVKYmLwOI7Q?hl=en) in front of the [Cordoaria Nacional](https://en.wikipedia.org/wiki/Cordoaria_Nacional) housing the [Ai Weiwei – Rapture](https://aiweiweilisboa.pt) exhibition.\n",
|
||||
"collection": "photos",
|
||||
"data": {
|
||||
"title": "Ai Weiwei, Forever Bicycles",
|
||||
"date": "2021-11-26T15:32:28.000Z",
|
||||
"image": {
|
||||
"src": "/@fs/Users/m/Code/blog/src/content/photos/2021-11-26-forever-bicycles/2021-11-26-forever-bicycles.jpg?origWidth=2781&origHeight=3746&origFormat=jpg",
|
||||
"width": 2781,
|
||||
"height": 3746,
|
||||
"format": "jpg",
|
||||
"orientation": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2021-11-26-law-of-the-journey/index.md",
|
||||
"slug": "2021-11-26-law-of-the-journey",
|
||||
"body": "\nDetail of Ai Weiwei's installation _Law of the Journey_ from 2017, looking at a print of _Odyssey_ from 2017. Inside the [Cordoaria Nacional](https://en.wikipedia.org/wiki/Cordoaria_Nacional) housing the [Ai Weiwei – Rapture](https://aiweiweilisboa.pt) exhibition in Lisbon, Portugal.\n\n> There’s no refugee crisis, but only human crisis… In dealing with refugees we’ve lost our very basic values.\n> — [Ai Weiwei, 2017](https://www.gessato.com/law-journey-ai-weiwei/)\n",
|
||||
"collection": "photos",
|
||||
"data": {
|
||||
"title": "Ai Weiwei, Law of the Journey",
|
||||
"date": "2021-11-26T16:12:03.000Z",
|
||||
"image": {
|
||||
"src": "/@fs/Users/m/Code/blog/src/content/photos/2021-11-26-law-of-the-journey/2021-11-26-law-of-the-journey.jpg?origWidth=3873&origHeight=2796&origFormat=jpg",
|
||||
"width": 3873,
|
||||
"height": 2796,
|
||||
"format": "jpg",
|
||||
"orientation": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
Loading…
Reference in New Issue
Block a user