Ocideck/test/markdown_service_test.dart

186 lines
6 KiB
Dart
Raw Permalink Normal View History

import 'package:flutter_test/flutter_test.dart';
import 'package:ocideck/models/deck.dart';
import 'package:ocideck/models/settings.dart';
import 'package:ocideck/models/slide.dart';
import 'package:ocideck/services/markdown_service.dart';
void main() {
test('round-trips image slide with title as image slide', () {
final service = MarkdownService();
final markdown = service.generateDeck(
Deck(
title: 'Demo',
slides: [
Slide.create(
SlideType.image,
).copyWith(title: 'Overlay title', imagePath: 'images/photo.png'),
],
),
);
final deck = service.parseDeck(markdown);
expect(deck, isNotNull);
expect(deck!.slides.single.type, SlideType.image);
expect(deck.slides.single.title, 'Overlay title');
expect(deck.slides.single.imagePath, 'images/photo.png');
});
test('round-trips bulletsImage slide with image and size', () {
final service = MarkdownService();
final markdown = service.generateDeck(
Deck(
title: 'Demo',
slides: [
Slide.create(SlideType.bulletsImage).copyWith(
title: 'Profiel',
bullets: ['Eerste punt', '\tGenest punt'],
imagePath: 'images/portret.png',
imageCaption: 'Een onderschrift',
imageSize: 45,
),
],
),
);
final deck = service.parseDeck(markdown);
expect(deck, isNotNull);
final slide = deck!.slides.single;
expect(slide.type, SlideType.bulletsImage);
expect(slide.title, 'Profiel');
expect(slide.imagePath, 'images/portret.png');
expect(slide.imageCaption, 'Een onderschrift');
expect(slide.imageSize, 45);
expect(slide.bullets, ['Eerste punt', '\tGenest punt']);
});
test('keeps a plain image inside free markdown as free markdown', () {
final service = MarkdownService();
final deck = service.parseDeck(
'---\nmarp: true\ntheme: vigilis\n---\n\n'
'![](images/inline.png)\n\nWat losse tekst.\n',
);
expect(deck, isNotNull);
final slide = deck!.slides.single;
expect(slide.type, SlideType.freeMarkdown);
expect(slide.imagePath, isEmpty);
});
test('round-trips deck style profile', () {
final service = MarkdownService();
final profile = const ThemeProfile(
name: 'Klant A',
slideBackgroundColor: '#111827',
textColor: '#F8FAFC',
accentColor: '#F59E0B',
tableTextColor: '#111111',
tableHeaderTextColor: '#EEEEEE',
logoPosition: 'top-left',
logoSize: 120,
fontFamily: 'Georgia',
footerText: 'Vertrouwelijk · {page}/{total}',
footerShowPageNumbers: true,
footerPosition: 'center',
closingSlideEnabled: true,
closingSlideMarkdown: '# Einde\n\nDank voor jullie aandacht.',
);
// The style profile only travels inside the markdown when explicitly
// inlined (transient beamer payloads); a plain save keeps the file clean.
final markdown = service.generateDeck(
Deck(
title: 'Demo',
themeProfile: profile,
slides: [Slide.create(SlideType.title).copyWith(title: 'Demo')],
),
inlineStyleProfile: true,
);
final deck = service.parseDeck(markdown);
expect(deck, isNotNull);
expect(deck!.themeProfile.name, 'Klant A');
expect(deck.themeProfile.slideBackgroundColor, '#111827');
expect(deck.themeProfile.tableTextColor, '#111111');
expect(deck.themeProfile.tableHeaderTextColor, '#EEEEEE');
expect(deck.themeProfile.logoPosition, 'top-left');
expect(deck.themeProfile.logoSize, 120);
expect(deck.themeProfile.fontFamily, 'Georgia');
expect(deck.themeProfile.footerText, 'Vertrouwelijk · {page}/{total}');
expect(deck.themeProfile.footerShowPageNumbers, isTrue);
expect(deck.themeProfile.footerPosition, 'center');
expect(deck.themeProfile.closingSlideEnabled, isTrue);
expect(
deck.themeProfile.closingSlideMarkdown,
'# Einde\n\nDank voor jullie aandacht.',
);
});
test('a saved deck does not embed the style profile', () {
final service = MarkdownService();
final markdown = service.generateDeck(
Deck(
title: 'Demo',
themeProfile: const ThemeProfile(
name: 'Klant A',
slideBackgroundColor: '#111827',
),
slides: [Slide.create(SlideType.title).copyWith(title: 'Demo')],
),
);
// The file is the base content only; styling stays out of it. Parsing it
// back yields the default profile, not the one that was saved.
expect(markdown.contains('ocideck_style_profile'), isFalse);
final deck = service.parseDeck(markdown);
expect(deck!.themeProfile.name, 'Standaard');
expect(deck.themeProfile.slideBackgroundColor, isNot('#111827'));
});
test('adds logo-safe class when deck profile has logo', () {
final service = MarkdownService();
final markdown = service.generateDeck(
Deck(
title: 'Demo',
themeProfile: const ThemeProfile(logoPath: '/tmp/logo.png'),
slides: [
Slide.create(
SlideType.bullets,
).copyWith(title: 'Demo', bullets: ['Een lange bullet']),
],
),
);
expect(markdown, contains('<!-- _class: logo-safe -->'));
});
test('round-trips video slide with audio attachment', () {
final service = MarkdownService();
final markdown = service.generateDeck(
Deck(
title: 'Media',
slides: [
Slide.create(SlideType.video).copyWith(
title: 'Film',
videoPath: 'media/movie.mp4',
videoAutoplay: true,
audioPath: 'media/narration.mp3',
audioAutoplay: true,
),
],
),
);
final deck = service.parseDeck(markdown);
expect(deck, isNotNull);
expect(deck!.slides.single.type, SlideType.video);
expect(deck.slides.single.videoPath, 'media/movie.mp4');
expect(deck.slides.single.videoAutoplay, isTrue);
expect(deck.slides.single.audioPath, 'media/narration.mp3');
expect(deck.slides.single.audioAutoplay, isTrue);
});
}