11import { shallowMount , flushPromises } from '@vue/test-utils'
22import App from '../../src/App.vue'
33
4+ // mock XMLHttpRequest for templates loading
5+ global . XMLHttpRequest = class XMLHttpRequest {
6+ private responseText : string
7+ private status : number
8+
9+ open ( method , templatePath ) {
10+ const templateName = templatePath . split ( '/' ) . pop ( )
11+
12+ switch ( templateName ) {
13+ case 'cover-template.html' :
14+ this . status = 200
15+ this . responseText = `<script type="x-tmpl-mustache">
16+ <div class="content-container">
17+ <div class="logo">
18+ <img src="{{{ metadata.logo }}}" alt="Logo">
19+ </div>
20+
21+ <div class="content">
22+ <h1>{{{ title }}}</h1>
23+
24+ <p>
25+ By: {{{ metadata.presenter }}}
26+ </p>
27+
28+ </div>
29+ </div>
30+ </script>
31+ `
32+ break
33+ case 'title-content-template.html' :
34+ this . status = 200
35+ this . responseText = `<script type="x-tmpl-mustache">
36+ <div class="content-container">
37+ <div class="title">
38+ <h1>
39+
40+ {{{ title }}}
41+
42+ </h1>
43+ <div class="logo">
44+ <img src="{{{ metadata.logo }}}" alt="Logo">
45+ </div>
46+ </div>
47+
48+ <div class="content-wrapper">
49+ <div class="content">
50+
51+ {{{ content }}}
52+
53+ </div>
54+ </div>
55+ </div>
56+ <footer>
57+ <div class="footer-content">{{{ metadata.footer }}}</div>
58+ <div class="custom-slide-number"></div>
59+ </footer>
60+ </script>
61+ `
62+ break
63+ case 'title-content-image-template.html' :
64+ this . status = 200
65+ this . responseText = `<script type="x-tmpl-mustache">
66+ <div class="content-container">
67+ <div class="title">
68+ <h1>
69+
70+ {{{ title }}}
71+
72+ </h1>
73+ <div class="logo">
74+ <img src="{{{ metadata.logo }}}" alt="Logo">
75+ </div>
76+ </div>
77+
78+ <div class="content-wrapper">
79+ <div class="content">
80+
81+ {{{ content }}}
82+
83+ </div>
84+ </div>
85+ </div>
86+ <footer>
87+ <div class="footer-content">{{{ metadata.footer }}}</div>
88+ <div class="custom-slide-number"></div>
89+ </footer>
90+ </script>
91+ `
92+ break
93+ case 'about-us-template.html' :
94+ this . status = 200
95+ this . responseText = `<script type="x-tmpl-mustache">
96+ <div class="content-container">
97+ <div class="title">
98+ <h1>
99+
100+ {{{ title }}}
101+
102+ </h1>
103+ <div class="logo">
104+ <img src="{{{ metadata.logo }}}" alt="Logo">
105+ </div>
106+ </div>
107+
108+ <div class="content-wrapper">
109+ <div class="content">
110+ <div class="about-us-text">
111+
112+ {{{ content }}}
113+
114+ </div>
115+ <div class="info-section">
116+
117+ {{#metadata.aboutUs}}
118+ <div class="info-box">
119+ <h3>{{ title }}</h3>
120+ <p>{{ text }}</p>
121+ </div>
122+ <div class="divider"></div>
123+ {{/metadata.aboutUs}}
124+
125+ </div>
126+
127+ </div>
128+ </div>
129+ </div>
130+ <footer>
131+ <div class="footer-content">{{{ metadata.footer }}}</div>
132+ <div class="custom-slide-number"></div>
133+ </footer>
134+ </script>
135+ `
136+ break
137+ default :
138+ this . status = 404
139+ return '<p>Template for slide "' + templateName + '" not found.</p>'
140+ }
141+ }
142+
143+ send ( ) {
144+ return
145+ }
146+ }
147+
4148// mock modules
5149vi . mock ( '@ownclouders/web-pkg' , ( ) => ( {
6150 useAppDefaults : vi . fn ( ) . mockImplementation ( ( ) => ( {
@@ -35,7 +179,7 @@ vi.mock('@ownclouders/web-pkg', () => ({
35179 AppLoadingSpinner : vi . fn ( )
36180} ) )
37181// global mocks
38- global . fetch = vi . fn ( ) . mockImplementation ( ( ) =>
182+ const defaultFetchMock = vi . fn ( ) . mockImplementation ( ( ) =>
39183 Promise . resolve ( {
40184 text : ( ) =>
41185 Promise . resolve ( `### Slide 1
@@ -96,6 +240,7 @@ code block
96240 )
97241 } )
98242)
243+ global . fetch = defaultFetchMock
99244URL . createObjectURL = vi
100245 . fn ( )
101246 . mockImplementation ( ( ) => 'blob:nodedata:0295bafb-5976-468a-a263-685a8872cb96' )
@@ -113,3 +258,88 @@ function getWrapper() {
113258 propsData : { url : 'https://localhost:9200/slides.md' }
114259 } )
115260}
261+
262+ // eslint-disable-next-line require-await
263+ describe ( 'Template Features' , async ( ) => {
264+ beforeEach ( ( ) => {
265+ global . fetch = defaultFetchMock
266+ } )
267+
268+ it ( 'should render slides with templates' , async ( ) => {
269+ global . fetch = vi . fn ( ) . mockImplementation ( ( ) => {
270+ return Promise . resolve ( {
271+ text : ( ) =>
272+ Promise . resolve ( `---
273+ slide: title-content
274+ presenter: John Doe
275+ logo: https://external:9200/cat.jpg
276+ aboutUs:
277+ - title: WWW
278+ text: www.example.com
279+ - title: LINKEDIN
280+ text: www.linkedin.com/company/example
281+ - title: FACEBOOK
282+ text: www.facebook.com/example
283+ - title: X
284+ text: www.x.com/example
285+ color: "#000"
286+ ---
287+ # Reveal js Templates in Web App Presentation Viewer ::slide:cover
288+
289+ ---
290+
291+ # Title Content Slide
292+
293+ - Introduction to mountain ecosystems
294+ - Basic concepts of quantum encryption
295+ - Exploring culinary traditions in Southeast Asia
296+ - Overview of blockchain consensus mechanisms
297+ - Setting up a personal productivity system
298+ - Writing clean, maintainable JavaScript code
299+ - Understanding modern art movements
300+ - History of aviation and early flight experiments
301+ - Managing team dynamics in remote work
302+
303+ ---
304+
305+ # Title Content Image Slide ::slide:title-content-image
306+
307+ - Introduction to mountain ecosystems
308+ - Basic concepts of quantum encryption
309+ - Exploring culinary traditions in Southeast Asia
310+ - Overview of blockchain consensus mechanisms
311+
312+ 
313+
314+ ---
315+
316+ # About Us ::slide:about-us
317+
318+ Some content about us.
319+ ` ) ,
320+ blob : ( ) => Promise . resolve ( new Blob ( [ ] , { type : 'text/markdown' } ) )
321+ } )
322+ } )
323+
324+ const vm = getWrapper ( )
325+ await flushPromises ( )
326+ await new Promise ( ( resolve ) => setTimeout ( resolve , 100 ) )
327+ expect ( vm . html ( ) ) . toMatchSnapshot ( )
328+ } )
329+
330+ it ( 'should return template not found error message' , async ( ) => {
331+ global . fetch = vi . fn ( ) . mockImplementation ( ( ) => {
332+ return Promise . resolve ( {
333+ text : ( ) =>
334+ Promise . resolve ( `---
335+ slide: non-existent
336+ ---
337+ ` ) ,
338+ blob : ( ) => Promise . resolve ( new Blob ( [ ] , { type : 'text/markdown' } ) )
339+ } )
340+ } )
341+ const vm = getWrapper ( )
342+ await flushPromises ( )
343+ expect ( vm . html ( ) ) . toContain ( 'Template for slide "non-existent" not found.' )
344+ } )
345+ } )
0 commit comments