@@ -2,6 +2,11 @@ import { test } from 'node:test';
22import assert from 'node:assert/strict' ;
33import fs from 'node:fs' ;
44import path from 'node:path' ;
5+ import {
6+ assignContentSocialImages ,
7+ buildContentSocialImage ,
8+ splitSocialTitle
9+ } from '../src/lib/social-images.ts' ;
510
611const root = process . cwd ( ) ;
712const read = ( ...parts ) => fs . readFileSync ( path . join ( root , ...parts ) , 'utf8' ) ;
@@ -10,6 +15,7 @@ const config = read('src', 'config', 'site.ts');
1015const base = read ( 'src' , 'layouts' , 'Base.astro' ) ;
1116const home = read ( 'src' , 'pages' , 'index.astro' ) ;
1217const about = read ( 'src' , 'pages' , 'about.astro' ) ;
18+ const detail = read ( 'src' , 'pages' , '[topic]' , '[slug].astro' ) ;
1319
1420test ( 'page groups use their intended social images' , ( ) => {
1521 assert . match ( config , / h o m e : ' h t t p s : \/ \/ r e s \. c l o u d i n a r y \. c o m \/ .+ \/ o g r a p h \/ h o m e _ [ ^ ' ] + \. p n g ' / ) ;
@@ -26,3 +32,51 @@ test('Open Graph and Twitter publish the same large image', () => {
2632 assert . match ( base , / n a m e = " t w i t t e r : i m a g e " c o n t e n t = \{ s o c i a l I m a g e \} / ) ;
2733 assert . match ( base , / n a m e = " t w i t t e r : i m a g e : a l t " c o n t e n t = \{ p a g e T i t l e \} / ) ;
2834} ) ;
35+
36+ test ( 'content pages use encoded Cloudinary title and topic layers' , ( ) => {
37+ const image = buildContentSocialImage (
38+ {
39+ title : 'Five DI Anti-Patterns Haunting .NET Apps and how to fix Them' ,
40+ topics : [ 'Dependency Injection' , 'C#' ]
41+ } ,
42+ 3
43+ ) ;
44+
45+ assert . equal (
46+ image ,
47+ 'https://res.cloudinary.com/dk3rdh3yo/image/upload/' +
48+ 'co_%23e83a47,l_text:Fira%20Mono_20:DEPENDENCY%20INJECTION%20%7C%20C%23/' +
49+ 'fl_layer_apply,g_north_west,x_60,y_60/' +
50+ 'w_630,c_fit,co_white,b_rgb:00000080,l_text:Archivo%20Black_60_line_spacing_-20:' +
51+ 'FIVE%20DI%20ANTI-PATTERNS%20HAUNTING%20.NET%20APPS/' +
52+ 'fl_layer_apply,g_south_west,x_60,y_180/' +
53+ 'bo_15px_solid_%23e83a47,b_%23e83a47,co_%23000000,l_text:Archivo%20Black_32:' +
54+ 'AND%20HOW%20TO%20FIX%20THEM,c_fit,w_600,h_50/' +
55+ 'fl_layer_apply,g_south_west,x_60,y_100/v1/ograph/ograph_3.png'
56+ ) ;
57+ assert . deepEqual ( splitSocialTitle ( 'A short title' ) , {
58+ main : 'A' ,
59+ ending : 'short title'
60+ } ) ;
61+ assert . match ( detail , / i m a g e = \{ s o c i a l I m a g e \} / ) ;
62+ assert . doesNotMatch ( detail , / i m a g e = \{ i t e m \. t h u m b n a i l / ) ;
63+ } ) ;
64+
65+ test ( 'content pages distribute backgrounds evenly in stable key order' , ( ) => {
66+ const content = Array . from ( { length : 14 } , ( _ , index ) => ( {
67+ key : `content:${ String ( index ) . padStart ( 2 , '0' ) } ` ,
68+ title : `Content title number ${ index } ` ,
69+ topics : [ 'C#' ]
70+ } ) ) . reverse ( ) ;
71+ const images = assignContentSocialImages ( content ) ;
72+ const counts = Array . from ( { length : 6 } , ( ) => 0 ) ;
73+
74+ for ( const image of images . values ( ) ) {
75+ const background = Number ( image . match ( / o g r a p h _ ( \d ) \. p n g $ / ) ?. [ 1 ] ) ;
76+ counts [ background - 1 ] += 1 ;
77+ }
78+
79+ assert . deepEqual ( counts , [ 3 , 3 , 2 , 2 , 2 , 2 ] ) ;
80+ assert . match ( images . get ( 'content:00' ) , / o g r a p h _ 1 \. p n g $ / ) ;
81+ assert . match ( images . get ( 'content:05' ) , / o g r a p h _ 6 \. p n g $ / ) ;
82+ } ) ;
0 commit comments