# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2022 OpenLP Developers #
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see . #
##########################################################################
"""
Package to test the openlp.plugins.planningcenter.lib.songimport package.
"""
import datetime
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common.registry import Registry
from openlp.plugins.planningcenter.lib.songimport import PlanningCenterSongImport
from tests.helpers.testmixin import TestMixin
class TestSongImport(TestCase, TestMixin):
"""
Test the PlanningcenterPlugin class
"""
def setUp(self):
"""
Create the class
"""
mocked_settings = MagicMock()
mocked_settings.value.return_value = 'english'
Registry.create()
self.registry = Registry()
self.registry.register('settings', mocked_settings)
self.registry.register('songs', MagicMock())
self.song_import = PlanningCenterSongImport()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.song_import
def test_add_song_without_lyrics(self):
"""
Test that a song can be added with None lyrics
"""
# GIVEN: A PlanningCenterSongImport Class
# WHEN: A song is added without lyrics
item_title = 'Title'
author = 'Author'
lyrics = None
theme_name = 'Theme Name'
last_modified = datetime.datetime.now()
with patch('openlp.plugins.songs.lib.importers.songimport.Song') as mock_song, \
patch('openlp.plugins.songs.lib.importers.songimport.Author'):
self.song_import.add_song(item_title, author, lyrics, theme_name, last_modified)
# THEN: A mock song has valid title, lyrics, and theme_name values
self.assertEqual(mock_song.return_value.title, item_title, "Mock Song Title matches input title")
self.assertTrue(item_title in mock_song.return_value.lyrics, "Mock Song Lyrics contain input title")
self.assertEqual(mock_song.return_value.theme_name, theme_name, "Mock Song Theme matches input theme")
def test_add_song_with_lyrics(self):
"""
Test that a song can be added with lyrics
"""
# GIVEN: A PlanningCenterSongImport Class
# WHEN: A song is added without lyrics
item_title = 'Title'
author = 'Author'
lyrics = 'This is my song!'
theme_name = 'Theme Name'
last_modified = datetime.datetime.now()
with patch('openlp.plugins.songs.lib.importers.songimport.Song') as mock_song, \
patch('openlp.plugins.songs.lib.importers.songimport.Author'):
self.song_import.add_song(item_title, author, lyrics, theme_name, last_modified)
# THEN: A mock song has valid title, lyrics, and theme_name values
self.assertEqual(mock_song.return_value.title, item_title, "Mock Song Title matches input title")
self.assertTrue(lyrics in mock_song.return_value.lyrics, "Mock Song Lyrics contain input lyrics")
self.assertEqual(mock_song.return_value.theme_name, theme_name, "Mock Song Theme matches input theme")
def test_add_song_with_verse(self):
"""
Test that a song can be added with lyrics that contain a verse header
"""
# GIVEN: A PlanningCenterSongImport Class
# WHEN: A song is added with lyrics that contain a verse tag
item_title = 'Title'
author = 'Author'
lyrics = 'V1\nThis is my song!'
theme_name = 'Theme Name'
last_modified = datetime.datetime.now()
with patch('openlp.plugins.songs.lib.importers.songimport.Song') as mock_song, \
patch('openlp.plugins.songs.lib.importers.songimport.Author'):
self.song_import.add_song(item_title, author, lyrics, theme_name, last_modified)
# THEN: A mock song has valid title, lyrics, and theme_name values
self.assertEqual(mock_song.return_value.title, item_title,
"Mock Song Title matches input title")
self.assertTrue("This is my song!" in mock_song.return_value.lyrics,
"Mock Song Lyrics contain input lyrics")
self.assertTrue("type=\"v\"" in mock_song.return_value.lyrics,
"Mock Song Lyrics contain input verse")
self.assertEqual(mock_song.return_value.theme_name, theme_name,
"Mock Song Theme matches input theme")
def test_parse_lyrics_with_end_marker(self):
"""
Test that a lyrics after an END marker are skipped
"""
# GIVEN: A PlanningCenterSongImport Class
# WHEN: _split_lyrics_into_verses is called with lyrics that contain an END marker
lyrics = 'This is my song!\n\n{END}\n\nSkip this part of the song'
output_verses = self.song_import._split_lyrics_into_verses(lyrics)
# THEN: A mock song has valid title, lyrics, and theme_name values
self.assertEqual(len(output_verses), 1, "A single verse is returned")
self.assertTrue("This is my song!" in output_verses[0]['verse_text'], "Output lyrics contain input lyrics")
self.assertFalse("END" in output_verses[0]['verse_text'], "Output Lyrics do not contain END")
self.assertFalse("Skip this part of the song" in output_verses[0]['verse_text'], "Output Lyrics stop at end")
def test_parse_lyrics_with_multiple_verses(self):
"""
Test lyrics with verse marker inside
"""
# GIVEN: A PlanningCenterSongImport Class
# WHEN: _split_lyrics_into_verses is called with lyrics that contain a verse marker inside (chorus)
lyrics = 'First Verse\n\nChorus\nThis is my Chorus\n'
output_verses = self.song_import._split_lyrics_into_verses(lyrics)
# THEN: A mock song has valid title, lyrics, and theme_name values
self.assertEqual(len(output_verses), 2, "Two output verses are returned")
self.assertEqual(output_verses[1]['verse_type'], 'c', "Second verse is a chorus")
def test_parse_lyrics_with_single_spaced_verse_tags(self):
"""
Test lyrics with verse marker inside
"""
# GIVEN: A PlanningCenterSongImport Class
# WHEN: _split_lyrics_into_verses is called with lyrics that contain a verse marker inside (chorus)
lyrics = 'V1\nFirst Verse\nV2\nSecondVerse\n'
output_verses = self.song_import._split_lyrics_into_verses(lyrics)
# THEN: A mock song has valid title, lyrics, and theme_name values
self.assertEqual(len(output_verses), 2, "Two output verses are returned")