@@ -10,16 +10,58 @@ import { describe, expect, it } from "vitest";
1010import { tutorialAppCaptures } from "@/lib/tutorial-app-captures" ;
1111
1212const expectedCaptureIds = [
13- "setupScanResults" ,
14- "setupConnectedIdentity" ,
13+ "setupFiveBoardScan" ,
14+ "identity5646Ready" ,
15+ "identity5646Chip" ,
16+ "identity8c9eReady" ,
17+ "identity8c9eChip" ,
18+ "identityc81aReady" ,
19+ "identityc81aChip" ,
20+ "identityda86Ready" ,
21+ "identityda86Chip" ,
22+ "identity3dcbReady" ,
23+ "identity3dcbChip" ,
1524 "firstProgramEditorConsole" ,
1625 "filesMultiDeleteReview" ,
1726 "githubBranchChooser" ,
18- "githubPrewriteReview" ,
27+ "githubPinnedSource" ,
28+ "githubTargetReview" ,
1929 "examplesImportComplete" ,
2030 "blocksHelloWorkspace" ,
2131] as const ;
2232
33+ const identityDimensions = {
34+ identity5646Ready : { width : 400 , height : 84 } ,
35+ identity5646Chip : { width : 512 , height : 390 } ,
36+ identity8c9eReady : { width : 400 , height : 84 } ,
37+ identity8c9eChip : { width : 512 , height : 390 } ,
38+ identityc81aReady : { width : 400 , height : 84 } ,
39+ identityc81aChip : { width : 512 , height : 390 } ,
40+ identityda86Ready : { width : 400 , height : 84 } ,
41+ identityda86Chip : { width : 512 , height : 390 } ,
42+ identity3dcbReady : { width : 400 , height : 84 } ,
43+ identity3dcbChip : { width : 512 , height : 390 } ,
44+ } as const ;
45+
46+ type CaptureRecord = {
47+ src : string ;
48+ alt : string ;
49+ width : number ;
50+ height : number ;
51+ provenance : {
52+ rawCapture : string ;
53+ processing : string ;
54+ depictedState : string ;
55+ review :
56+ | { status : "pending-derivative" ; sha256 : null }
57+ | { status : "reviewed" ; sha256 : string } ;
58+ } ;
59+ } ;
60+
61+ const captures = tutorialAppCaptures as unknown as Record <
62+ string ,
63+ CaptureRecord | undefined
64+ > ;
2365const pngSignature = Buffer . from ( [ 137 , 80 , 78 , 71 , 13 , 10 , 26 , 10 ] ) ;
2466const forbiddenMetadataChunks = new Set ( [
2567 "eXIf" ,
@@ -37,21 +79,17 @@ function pngChunkTypes(bytes: Buffer): string[] {
3779 const dataLength = bytes . readUInt32BE ( offset ) ;
3880 const chunkEnd = offset + 12 + dataLength ;
3981 expect ( chunkEnd ) . toBeLessThanOrEqual ( bytes . length ) ;
40-
4182 const chunkType = bytes . toString ( "ascii" , offset + 4 , offset + 8 ) ;
4283 chunkTypes . push ( chunkType ) ;
4384 offset = chunkEnd ;
44-
45- if ( chunkType === "IEND" ) {
46- break ;
47- }
85+ if ( chunkType === "IEND" ) break ;
4886 }
4987
5088 return chunkTypes ;
5189}
5290
5391describe ( "reviewed physical tutorial capture assets" , ( ) => {
54- it ( "keeps the reviewed capture registry complete and unique" , ( ) => {
92+ it ( "keeps the five-board capture registry complete and unique" , ( ) => {
5593 expect ( Object . keys ( tutorialAppCaptures ) ) . toEqual ( expectedCaptureIds ) ;
5694 expect (
5795 new Set ( Object . values ( tutorialAppCaptures ) . map ( ( { src } ) => src ) ) . size ,
@@ -61,24 +99,31 @@ describe("reviewed physical tutorial capture assets", () => {
6199 it . each ( expectedCaptureIds ) (
62100 "%s binds content-versioned, stripped PNG bytes to reviewed provenance" ,
63101 async ( captureId ) => {
64- const capture = tutorialAppCaptures [ captureId ] ;
65- const { review } = capture . provenance ;
102+ const capture = captures [ captureId ] ;
103+ expect ( capture ) . toBeDefined ( ) ;
104+ if ( ! capture ) return ;
66105
67- if ( review . status !== "reviewed" ) {
68- throw new Error ( ` ${ captureId } has not completed derivative review` ) ;
69- }
106+ const { review } = capture . provenance ;
107+ expect ( review . status ) . toBe ( "reviewed" ) ;
108+ if ( review . status !== "reviewed" ) return ;
70109
71110 expect ( review . sha256 ) . toMatch ( / ^ [ 0 - 9 a - f ] { 64 } $ / ) ;
72111 expect ( basename ( capture . src ) ) . toContain ( review . sha256 . slice ( 0 , 12 ) ) ;
73112 expect ( capture . src ) . not . toContain ( "pending" ) ;
74- expect ( capture . provenance . rawCapture ) . toMatch (
75- / p r o d u c t i o n - r e l e a s e \. r a w \. p n g $ / ,
76- ) ;
113+ expect ( capture . provenance . rawCapture ) . toMatch ( / \. r a w \. p n g $ / ) ;
77114 expect ( capture . provenance . rawCapture ) . not . toMatch (
78- / d e b u g | g o l d e n | i n t e g r a t i o n / i,
115+ / d e b u g | g o l d e n | i n t e g r a t i o n | i p a d / i,
79116 ) ;
80117 expect ( capture . provenance . processing ) . toMatch (
81- / c r o p .* s t a t u s .* n a v i g a t i o n .* s t r i p m e t a d a t a .* n o t r e t o u c h / is,
118+ / c r o p .* s t r i p m e t a d a t a .* n o t r e t o u c h / is,
119+ ) ;
120+
121+ const expectedDimensions =
122+ captureId in identityDimensions
123+ ? identityDimensions [ captureId as keyof typeof identityDimensions ]
124+ : { width : 2000 , height : 1092 } ;
125+ expect ( { width : capture . width , height : capture . height } ) . toEqual (
126+ expectedDimensions ,
82127 ) ;
83128
84129 const asset = await readFile (
@@ -87,10 +132,6 @@ describe("reviewed physical tutorial capture assets", () => {
87132 expect ( asset . subarray ( 0 , pngSignature . length ) ) . toEqual ( pngSignature ) ;
88133 expect ( asset . readUInt32BE ( 16 ) ) . toBe ( capture . width ) ;
89134 expect ( asset . readUInt32BE ( 20 ) ) . toBe ( capture . height ) ;
90- expect ( { width : capture . width , height : capture . height } ) . toEqual ( {
91- width : 2000 ,
92- height : 1092 ,
93- } ) ;
94135 expect ( createHash ( "sha256" ) . update ( asset ) . digest ( "hex" ) ) . toBe (
95136 review . sha256 ,
96137 ) ;
@@ -105,4 +146,19 @@ describe("reviewed physical tutorial capture assets", () => {
105146 ) . toEqual ( [ ] ) ;
106147 } ,
107148 ) ;
149+
150+ it ( "keeps both S3 observations truthful and non-identifying" , ( ) => {
151+ expect ( captures . identity5646Ready ?. provenance . depictedState ) . toMatch (
152+ / 5 6 4 6 .* 0 \. 6 \. 0 / is,
153+ ) ;
154+ expect ( captures . identityda86Ready ?. provenance . depictedState ) . toMatch (
155+ / D A 8 6 .* 0 \. 6 \. 0 / is,
156+ ) ;
157+ expect ( captures . identity5646Chip ?. provenance . depictedState ) . toMatch (
158+ / e s p 3 2 - s 3 .* n o t .* p r o f i l e / is,
159+ ) ;
160+ expect ( captures . identityda86Chip ?. provenance . depictedState ) . toMatch (
161+ / e s p 3 2 - s 3 .* n o t .* p r o f i l e / is,
162+ ) ;
163+ } ) ;
108164} ) ;
0 commit comments