1+ import { describe , it , expect , vi , beforeEach } from "vitest" ;
2+ import {
3+ CanvasBug ,
4+ IgniteBug ,
5+ InstructureBug ,
6+ MasteryBug ,
7+ StudioBug ,
8+ ParchmentBug ,
9+ } from "./Logos" ;
10+ import { render } from "@testing-library/react" ;
11+ import { InlineSVG } from "@instructure/ui" ;
12+
13+ // Mock InlineSVG to inspect props and children
14+ vi . mock ( "@instructure/ui" , async ( orig ) => {
15+ const mod = await orig ( ) ;
16+ // Define InlineSVGMock inside the factory to avoid hoisting issues
17+ const InlineSVGMock = vi . fn ( ( { children, ...props } ) => (
18+ < svg data-testid = "inline-svg" { ...props } >
19+ { children }
20+ </ svg >
21+ ) ) ;
22+ return {
23+ ...( typeof mod === "object" && mod !== null ? mod : { } ) ,
24+ InlineSVG : InlineSVGMock ,
25+ } ;
26+ } ) ;
27+
28+ // Mock useId to return a stable value for IgniteBug
29+ vi . mock ( "react" , async ( orig ) => {
30+ const mod = await orig ( ) ;
31+ return {
32+ ...( typeof mod === "object" && mod !== null ? mod : { } ) ,
33+ useId : ( ) => "testid" ,
34+ } ;
35+ } ) ;
36+
37+ const InlineSVGMock = InlineSVG as unknown as ReturnType < typeof vi . fn > ;
38+
39+ describe ( "Logo Bug Components" , ( ) => {
40+ beforeEach ( ( ) => {
41+ InlineSVGMock . mockClear ( ) ;
42+ } ) ;
43+
44+ const logoCases = [
45+ {
46+ name : "CanvasBug" ,
47+ Component : CanvasBug ,
48+ expected : {
49+ title : "Canvas" ,
50+ viewBox : "0 0 59.68 59.68" ,
51+ } ,
52+ } ,
53+ {
54+ name : "MasteryBug" ,
55+ Component : MasteryBug ,
56+ expected : {
57+ title : "Mastery" ,
58+ viewBox : "0 0 70.82 53.92" ,
59+ } ,
60+ } ,
61+ {
62+ name : "StudioBug" ,
63+ Component : StudioBug ,
64+ expected : {
65+ title : "Studio" ,
66+ viewBox : "0 0 135.85 118.73" ,
67+ } ,
68+ } ,
69+ {
70+ name : "ParchmentBug" ,
71+ Component : ParchmentBug ,
72+ expected : {
73+ title : "Parchment" ,
74+ viewBox : "0 0 70.82 53.92" ,
75+ } ,
76+ } ,
77+ ] ;
78+
79+ logoCases . forEach ( ( { name, Component, expected } ) => {
80+ it ( `${ name } renders with default props` , ( ) => {
81+ render ( < Component /> ) ;
82+ expect ( InlineSVGMock ) . toHaveBeenCalledWith (
83+ expect . objectContaining ( {
84+ title : expected . title ,
85+ viewBox : expected . viewBox ,
86+ } ) ,
87+ undefined ,
88+ ) ;
89+ } ) ;
90+
91+ it ( `${ name } passes color prop and wraps children in <g fill>` , ( ) => {
92+ const { getAllByTestId } = render ( < Component color = "#123456" /> ) ;
93+ const svg = getAllByTestId ( "inline-svg" ) . pop ( ) ;
94+ if ( ! svg ) throw new Error ( "SVG not found" ) ;
95+ const g = svg . querySelector ( "g[fill='#123456']" ) ;
96+ expect ( g ) . not . toBeNull ( ) ;
97+ } ) ;
98+ } ) ;
99+
100+ it ( "InstructureBug renders with default props" , ( ) => {
101+ render ( < InstructureBug /> ) ;
102+ expect ( InlineSVGMock ) . toHaveBeenCalledWith (
103+ expect . objectContaining ( {
104+ title : "Instructure" ,
105+ viewBox : "0 0 53.42 53.42" ,
106+ } ) ,
107+ undefined ,
108+ ) ;
109+ } ) ;
110+
111+ it ( "InstructureBug renders with color and custom fills" , ( ) => {
112+ const { getAllByTestId } = render ( < InstructureBug color = "#abc" /> ) ;
113+ const svg = getAllByTestId ( "inline-svg" ) . pop ( ) ;
114+ expect ( svg ) . toBeTruthy ( ) ;
115+ if ( ! svg ) throw new Error ( "SVG not found" ) ;
116+ const rects = svg . querySelectorAll ( "rect" ) ;
117+ expect ( rects . length ) . toBeGreaterThan ( 0 ) ;
118+ expect ( rects [ 0 ] . getAttribute ( "stroke" ) ) . toBe ( "#0E1721" ) ;
119+ expect ( rects [ 1 ] . getAttribute ( "fill" ) ) . toBe ( "#0E1721" ) ;
120+ const path = svg . querySelector ( "path" ) ;
121+ expect ( path ) . not . toBeNull ( ) ;
122+ if ( ! path ) throw new Error ( "path not found" ) ;
123+ expect ( path . getAttribute ( "fill" ) ) . toBe ( "#D42E21" ) ;
124+ } ) ;
125+
126+ it ( "IgniteBug renders with default props (no color)" , ( ) => {
127+ render ( < IgniteBug /> ) ;
128+ const call = InlineSVGMock . mock . calls [ 0 ] [ 0 ] ;
129+ expect ( call . title ) . toBe ( "IgniteAI" ) ;
130+ expect ( call . viewBox ) . toBe ( "0 0 1920 1920" ) ;
131+ } ) ;
132+
133+ it ( "IgniteBug renders with color and gradients/defs" , ( ) => {
134+ const { getAllByTestId } = render ( < IgniteBug color = "#f00" /> ) ;
135+ const svg = getAllByTestId ( "inline-svg" ) . pop ( ) ;
136+ expect ( svg ) . toBeTruthy ( ) ;
137+ if ( ! svg ) throw new Error ( "SVG not found" ) ;
138+ const defs = svg . querySelector ( "defs" ) ;
139+ expect ( defs ) . not . toBeNull ( ) ;
140+ if ( ! defs ) throw new Error ( "defs not found" ) ;
141+ const grad = defs . querySelector ( "linearGradient#paint0_linear_testid" ) ;
142+ expect ( grad ) . not . toBeNull ( ) ;
143+ const clip = defs . querySelector ( "clipPath#clip0_testid" ) ;
144+ expect ( clip ) . not . toBeNull ( ) ;
145+ const g = svg . querySelector ( "g[clip-path='url(#clip0_testid)']" ) ;
146+ expect ( g ) . not . toBeNull ( ) ;
147+ } ) ;
148+
149+ it ( "All logo bug components render without crashing" , ( ) => {
150+ expect ( ( ) => {
151+ render ( < CanvasBug /> ) ;
152+ render ( < MasteryBug /> ) ;
153+ render ( < StudioBug /> ) ;
154+ render ( < ParchmentBug /> ) ;
155+ render ( < IgniteBug /> ) ;
156+ render ( < InstructureBug /> ) ;
157+ } ) . not . toThrow ( ) ;
158+ } ) ;
159+ } ) ;
0 commit comments