コード例 #1
0
    def test_save_song_unknown_author(self, MockedAuthor, mocked_clean_song):
        """
        Test that saving a song with an author name of only one word performs the correct actions
        """
        # GIVEN: A song to save, and some mocked out objects
        song_dict = {
            'title': 'Arky Arky',
            'authors': ['Unknown'],
            'verses': [
                {'label': 'Verse 1', 'lyrics': 'The Lord told Noah: there\'s gonna be a floody, floody'},
                {'label': 'Chorus 1', 'lyrics': 'So, rise and shine, and give God the glory, glory'},
                {'label': 'Verse 2', 'lyrics': 'The Lord told Noah to build him an arky, arky'}
            ],
            'copyright': 'Public Domain',
            'ccli_number': '123456'
        }
        MockedAuthor.display_name.__eq__.return_value = False
        mocked_db_manager = MagicMock()
        mocked_db_manager.get_object_filtered.return_value = None
        importer = SongSelectImport(mocked_db_manager)

        # WHEN: The song is saved to the database
        result = importer.save_song(song_dict)

        # THEN: The return value should be a Song class and the mocked_db_manager should have been called
        assert isinstance(result, Song), 'The returned value should be a Song object'
        mocked_clean_song.assert_called_with(mocked_db_manager, result)
        assert 2 == mocked_db_manager.save_object.call_count, \
            'The save_object() method should have been called twice'
        mocked_db_manager.get_object_filtered.assert_called_with(MockedAuthor, False)
        MockedAuthor.populate.assert_called_with(first_name='Unknown', last_name='', display_name='Unknown')
        assert 1 == len(result.authors_songs), 'There should only be one author'
コード例 #2
0
ファイル: test_songselect.py プロジェクト: simhnna/openlp
    def test_get_song(self, MockedBeautifulSoup, mocked_build_opener):
        """
        Test that the get_song() method returns the correct song details
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        mocked_song_page = MagicMock()
        mocked_copyright = MagicMock()
        mocked_copyright.find_all.return_value = [
            MagicMock(string='Copyright 1'),
            MagicMock(string='Copyright 2')
        ]
        mocked_song_page.find.side_effect = [
            mocked_copyright,
            MagicMock(find=MagicMock(string='CCLI: 123456'))
        ]
        mocked_lyrics_page = MagicMock()
        mocked_find_all = MagicMock()
        mocked_find_all.side_effect = [[
            MagicMock(
                contents=
                'The Lord told Noah: there\'s gonna be a floody, floody'),
            MagicMock(
                contents='So, rise and shine, and give God the glory, glory'),
            MagicMock(contents='The Lord told Noah to build him an arky, arky')
        ],
                                       [
                                           MagicMock(string='Verse 1'),
                                           MagicMock(string='Chorus'),
                                           MagicMock(string='Verse 2')
                                       ]]
        mocked_lyrics_page.find.return_value = MagicMock(
            find_all=mocked_find_all)
        MockedBeautifulSoup.side_effect = [
            mocked_song_page, mocked_lyrics_page
        ]
        mocked_callback = MagicMock()
        importer = SongSelectImport(None)
        fake_song = {
            'title': 'Title',
            'authors': ['Author 1', 'Author 2'],
            'link': 'url'
        }

        # WHEN: get_song is called
        result = importer.get_song(fake_song, callback=mocked_callback)

        # THEN: The callback should have been called three times and the song should be returned
        assert 3 == mocked_callback.call_count, 'The callback should have been called twice'
        assert result is not None, 'The get_song() method should have returned a song dictionary'
        assert 2 == mocked_lyrics_page.find.call_count, 'The find() method should have been called twice'
        assert 2 == mocked_find_all.call_count, 'The find_all() method should have been called twice'
        assert [call('div', 'song-viewer lyrics'), call('div', 'song-viewer lyrics')] == \
            mocked_lyrics_page.find.call_args_list, 'The find() method should have been called with the right arguments'
        assert [call('p'), call('h3')] == mocked_find_all.call_args_list, \
            'The find_all() method should have been called with the right arguments'
        assert 'copyright' in result, 'The returned song should have a copyright'
        assert 'ccli_number' in result, 'The returned song should have a CCLI number'
        assert 'verses' in result, 'The returned song should have verses'
        assert 3 == len(
            result['verses']), 'Three verses should have been returned'
コード例 #3
0
    def test_search_returns_no_results(self, MockedBeautifulSoup,
                                       mocked_build_opener):
        """
        Test that when the search finds no results, it simply returns an empty list
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        mocked_opener = MagicMock()
        mocked_build_opener.return_value = mocked_opener
        mocked_results_page = MagicMock()
        mocked_results_page.find_all.return_value = []
        MockedBeautifulSoup.return_value = mocked_results_page
        mock_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: The login method is called after being rigged to fail
        results = importer.search('text', 1000, mock_callback)

        # THEN: callback was never called, open was called once, find_all was called once, an empty list returned
        self.assertEqual(0, mock_callback.call_count,
                         'callback should not have been called')
        self.assertEqual(1, mocked_opener.open.call_count,
                         'open should have been called once')
        self.assertEqual(1, mocked_results_page.find_all.call_count,
                         'find_all should have been called once')
        mocked_results_page.find_all.assert_called_with('div', 'song-result')
        self.assertEqual(
            [], results,
            'The search method should have returned an empty list')
コード例 #4
0
 def initialise(self):
     """
     Initialise the SongSelectForm
     """
     self.thread = None
     self.worker = None
     self.song_count = 0
     self.song = None
     self.set_progress_visible(False)
     self.song_select_importer = SongSelectImport(self.db_manager)
     self.save_password_checkbox.toggled.connect(
         self.on_save_password_checkbox_toggled)
     self.login_button.clicked.connect(self.on_login_button_clicked)
     self.search_button.clicked.connect(self.on_search_button_clicked)
     self.search_combobox.returnPressed.connect(
         self.on_search_button_clicked)
     self.stop_button.clicked.connect(self.on_stop_button_clicked)
     self.logout_button.clicked.connect(self.done)
     self.search_results_widget.itemDoubleClicked.connect(
         self.on_search_results_widget_double_clicked)
     self.search_results_widget.itemSelectionChanged.connect(
         self.on_search_results_widget_selection_changed)
     self.view_button.clicked.connect(self.on_view_button_clicked)
     self.back_button.clicked.connect(self.on_back_button_clicked)
     self.import_button.clicked.connect(self.on_import_button_clicked)
コード例 #5
0
ファイル: test_songselect.py プロジェクト: simhnna/openlp
    def test_login_fails(self, MockedBeautifulSoup, mocked_build_opener):
        """
        Test that when logging in to SongSelect fails, the login method returns False
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        mocked_opener = MagicMock()
        mocked_build_opener.return_value = mocked_opener
        mocked_login_page = MagicMock()
        mocked_login_page.find.side_effect = [{'value': 'blah'}, None]
        mocked_posted_page = MagicMock()
        mocked_posted_page.find.return_value = None
        MockedBeautifulSoup.side_effect = [
            mocked_login_page, mocked_posted_page
        ]
        mock_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: The login method is called after being rigged to fail
        result = importer.login('username', 'password', mock_callback)

        # THEN: callback was called 3 times, open was called twice, find was called twice, and False was returned
        assert 3 == mock_callback.call_count, 'callback should have been called 3 times'
        assert 2 == mocked_login_page.find.call_count, 'find should have been called twice'
        assert 1 == mocked_posted_page.find.call_count, 'find should have been called once'
        assert 2 == mocked_opener.open.call_count, 'opener should have been called twice'
        assert result is False, 'The login method should have returned False'
コード例 #6
0
    def test_login_url_from_form(self, MockedBeautifulSoup, mocked_build_opener):
        """
        Test that the login URL is from the form
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        mocked_opener = MagicMock()
        mocked_build_opener.return_value = mocked_opener
        mocked_form = MagicMock()
        mocked_form.attrs = {'action': 'do/login'}
        mocked_login_page = MagicMock()
        mocked_login_page.find.side_effect = [{'value': 'blah'}, mocked_form]
        mocked_posted_page = MagicMock()
        mocked_posted_page.find.return_value = MagicMock()
        mocked_home_page = MagicMock()
        MockedBeautifulSoup.side_effect = [mocked_login_page, mocked_posted_page, mocked_home_page]
        mock_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: The login method is called after being rigged to fail
        result = importer.login('username', 'password', mock_callback)

        # THEN: callback was called 3 times, open was called twice, find was called twice, and True was returned
        assert 3 == mock_callback.call_count, 'callback should have been called 3 times'
        assert 2 == mocked_login_page.find.call_count, 'find should have been called twice on the login page'
        assert 1 == mocked_posted_page.find.call_count, 'find should have been called once on the posted page'
        assert 'https://profile.ccli.com/do/login', mocked_opener.open.call_args_list[1][0][0]
        assert result is None, 'The login method should have returned the subscription level'
コード例 #7
0
    def test_search_returns_ccli_song_number_result(self, MockedBeautifulSoup, mocked_build_opener):
        """
        Test that search can find a single song by CCLI number
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        mocked_opener = MagicMock()
        mocked_build_opener.return_value = mocked_opener
        mocked_results_page = MagicMock()
        mocked_results_page.find_all.return_value = []
        MockedBeautifulSoup.return_value = mocked_results_page
        mock_callback = MagicMock()
        importer = SongSelectImport(None)
        importer.subscription_level = 'premium'

        # WHEN: The search is performed
        results = importer.search('1234567', 1000, mock_callback)

        # THEN: callback was called once and the results are as expected
        assert 1 == mock_callback.call_count, 'callback should not have been called'
        assert 1 == mocked_opener.open.call_count, 'open should have been called once'
        assert 1 == mocked_results_page.find_all.call_count, 'find_all should have been called once'
        mocked_results_page.find_all.assert_called_with('div', 'song-result')

        assert 1 == len(results), 'The search method should have returned an single song in a list'
        assert 'https://songselect.ccli.com/Songs/1234567' == results[0]['link'],\
            'The correct link should have been returned'
コード例 #8
0
ファイル: test_songselect.py プロジェクト: simhnna/openlp
    def test_search_reaches_max_results(self, MockedBeautifulSoup,
                                        mocked_build_opener):
        """
        Test that when the search finds MAX (2) results, it simply returns a list with those (2)
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        # first search result
        mocked_result1 = MagicMock()
        mocked_result1.find.side_effect = [
            MagicMock(find=MagicMock(return_value=MagicMock(
                string='Title 1'))),
            MagicMock(string='James, John'),
            MagicMock(find=MagicMock(return_value={'href': '/url1'}))
        ]
        # second search result
        mocked_result2 = MagicMock()
        mocked_result2.find.side_effect = [
            MagicMock(find=MagicMock(return_value=MagicMock(
                string='Title 2'))),
            MagicMock(string='Philip'),
            MagicMock(find=MagicMock(return_value={'href': '/url2'}))
        ]
        # third search result
        mocked_result3 = MagicMock()
        mocked_result3.find.side_effect = [
            MagicMock(find=MagicMock(return_value=MagicMock(
                string='Title 3'))),
            MagicMock(string='Luke, Matthew'),
            MagicMock(find=MagicMock(return_value={'href': '/url3'}))
        ]
        # rest of the stuff
        mocked_opener = MagicMock()
        mocked_build_opener.return_value = mocked_opener
        mocked_results_page = MagicMock()
        mocked_results_page.find_all.side_effect = [[
            mocked_result1, mocked_result2, mocked_result3
        ], []]
        MockedBeautifulSoup.return_value = mocked_results_page
        mock_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: The search method is called
        results = importer.search('text', 2, mock_callback)

        # THEN: callback was called twice, open was called twice, find_all was called twice, max results returned
        assert 2 == mock_callback.call_count, 'callback should have been called twice'
        assert 2 == mocked_opener.open.call_count, 'open should have been called twice'
        assert 2 == mocked_results_page.find_all.call_count, 'find_all should have been called twice'
        mocked_results_page.find_all.assert_called_with('div', 'song-result')
        expected_list = [{
            'title': 'Title 1',
            'authors': ['James', 'John'],
            'link': BASE_URL + '/url1'
        }, {
            'title': 'Title 2',
            'authors': ['Philip'],
            'link': BASE_URL + '/url2'
        }]
        assert expected_list == results, 'The search method should have returned two songs'
コード例 #9
0
    def test_search_returns_two_results(self, MockedBeautifulSoup,
                                        mocked_build_opener):
        """
        Test that when the search finds 2 results, it simply returns a list with 2 results
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        # first search result
        mocked_result1 = MagicMock()
        mocked_result1.find.side_effect = [
            MagicMock(find=MagicMock(return_value=MagicMock(
                string='Title 1'))),
            MagicMock(string='James, John'),
            MagicMock(find=MagicMock(return_value={'href': '/url1'}))
        ]
        # second search result
        mocked_result2 = MagicMock()
        mocked_result2.find.side_effect = [
            MagicMock(find=MagicMock(return_value=MagicMock(
                string='Title 2'))),
            MagicMock(string='Philip'),
            MagicMock(find=MagicMock(return_value={'href': '/url2'}))
        ]
        # rest of the stuff
        mocked_opener = MagicMock()
        mocked_build_opener.return_value = mocked_opener
        mocked_results_page = MagicMock()
        mocked_results_page.find_all.side_effect = [[
            mocked_result1, mocked_result2
        ], []]
        MockedBeautifulSoup.return_value = mocked_results_page
        mock_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: The search method is called
        results = importer.search('text', 1000, mock_callback)

        # THEN: callback was never called, open was called once, find_all was called once, an empty list returned
        self.assertEqual(2, mock_callback.call_count,
                         'callback should have been called twice')
        self.assertEqual(2, mocked_opener.open.call_count,
                         'open should have been called twice')
        self.assertEqual(2, mocked_results_page.find_all.call_count,
                         'find_all should have been called twice')
        mocked_results_page.find_all.assert_called_with('div', 'song-result')
        expected_list = [{
            'title': 'Title 1',
            'authors': ['James', 'John'],
            'link': BASE_URL + '/url1'
        }, {
            'title': 'Title 2',
            'authors': ['Philip'],
            'link': BASE_URL + '/url2'
        }]
        self.assertListEqual(
            expected_list, results,
            'The search method should have returned two songs')
コード例 #10
0
    def test_stop_called(self, MockedBeautifulSoup, mocked_build_opener):
        """
        Test that the search is stopped with stop() is called
        """
        # GIVEN: An importer object that is currently "searching"
        importer = SongSelectImport(None)
        importer.run_search = True

        # WHEN: The stop method is called
        importer.stop()

        # THEN: Searching should have stopped
        assert importer.run_search is False, 'Searching should have been stopped'
コード例 #11
0
    def test_constructor(self, mocked_build_opener):
        """
        Test that constructing a basic SongSelectImport object works correctly
        """
        # GIVEN: The SongSelectImporter class and a mocked out build_opener
        # WHEN: An object is instantiated
        importer = SongSelectImport(None)

        # THEN: The object should have the correct properties
        assert importer.db_manager is None, 'The db_manager should be None'
        assert importer.html_parser is not None, 'There should be a valid html_parser object'
        assert importer.opener is not None, 'There should be a valid opener object'
        assert 1 == mocked_build_opener.call_count, 'The build_opener method should have been called once'
コード例 #12
0
ファイル: test_songselect.py プロジェクト: jkunle/paul
    def save_song_existing_author_test(self, MockedAuthor, mocked_clean_song):
        """
        Test that saving a song with an existing author performs the correct actions
        """
        # GIVEN: A song to save, and some mocked out objects
        song_dict = {
            'title':
            'Arky Arky',
            'authors': ['Public Domain'],
            'verses': [{
                'label':
                'Verse 1',
                'lyrics':
                'The Lord told Noah: there\'s gonna be a floody, floody'
            }, {
                'label':
                'Chorus 1',
                'lyrics':
                'So, rise and shine, and give God the glory, glory'
            }, {
                'label':
                'Verse 2',
                'lyrics':
                'The Lord told Noah to build him an arky, arky'
            }],
            'copyright':
            'Public Domain',
            'ccli_number':
            '123456'
        }
        MockedAuthor.display_name.__eq__.return_value = False
        mocked_db_manager = MagicMock()
        mocked_db_manager.get_object_filtered.return_value = MagicMock()
        importer = SongSelectImport(mocked_db_manager)

        # WHEN: The song is saved to the database
        result = importer.save_song(song_dict)

        # THEN: The return value should be a Song class and the mocked_db_manager should have been called
        self.assertIsInstance(result, Song,
                              'The returned value should be a Song object')
        mocked_clean_song.assert_called_with(mocked_db_manager, result)
        self.assertEqual(
            2, mocked_db_manager.save_object.call_count,
            'The save_object() method should have been called twice')
        mocked_db_manager.get_object_filtered.assert_called_with(
            MockedAuthor, False)
        self.assertEqual(0, MockedAuthor.populate.call_count,
                         'A new author should not have been instantiated')
        self.assertEqual(1, len(result.authors_songs),
                         'There should only be one author')
コード例 #13
0
    def test_login_except(self, mocked_build_opener):
        """
        Test that when logging in to SongSelect fails, the login method raises URLError
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        mocked_build_opener.open.side_effect = URLError('Fake URLError')
        mock_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: The login method is called after being rigged to fail
        result = importer.login('username', 'password', mock_callback)

        # THEN: callback was called 1 time and False was returned
        assert 1 == mock_callback.call_count, 'callback should have been called 1 times'
        assert result is False, 'The login method should have returned False'
コード例 #14
0
    def test_logout(self, mocked_build_opener):
        """
        Test that when the logout method is called, it logs the user out of SongSelect
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        mocked_opener = MagicMock()
        mocked_build_opener.return_value = mocked_opener
        importer = SongSelectImport(None)

        # WHEN: The login method is called after being rigged to fail
        importer.logout()

        # THEN: The opener is called once with the logout url
        assert 1 == mocked_opener.open.call_count, 'opener should have been called once'
        mocked_opener.open.assert_called_with(LOGOUT_URL)
コード例 #15
0
    def test_get_song_lyrics_raise_exception(self, MockedBeautifulSoup, mocked_build_opener):
        """
        Test that when BeautifulSoup gets a bad lyrics page the get_song() method returns None
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        song_page = MagicMock(return_value={'href': '/lyricpage'})
        MockedBeautifulSoup.side_effect = [song_page, TypeError('Test Error')]
        mocked_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: get_song is called
        result = importer.get_song({'link': 'link'}, callback=mocked_callback)

        # THEN: The callback should have been called twice and None should be returned
        assert 2 == mocked_callback.call_count, 'The callback should have been called twice'
        assert result is None, 'The get_song() method should have returned None'
コード例 #16
0
    def test_get_song_page_raises_exception(self, mocked_build_opener):
        """
        Test that when BeautifulSoup gets a bad song page the get_song() method returns None
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        mocked_opener = MagicMock()
        mocked_build_opener.return_value = mocked_opener
        mocked_opener.open.read.side_effect = URLError('[Errno -2] Name or service not known')
        mocked_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: get_song is called
        result = importer.get_song({'link': 'link'}, callback=mocked_callback)

        # THEN: The callback should have been called once and None should be returned
        mocked_callback.assert_called_with()
        assert result is None, 'The get_song() method should have returned None'
コード例 #17
0
ファイル: test_songselect.py プロジェクト: jkunle/paul
    def get_song_lyrics_raise_exception_test(self, MockedBeautifulSoup,
                                             mocked_build_opener):
        """
        Test that when BeautifulSoup gets a bad lyrics page the get_song() method returns None
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        MockedBeautifulSoup.side_effect = [None, TypeError('Test Error')]
        mocked_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: get_song is called
        result = importer.get_song({'link': 'link'}, callback=mocked_callback)

        # THEN: The callback should have been called twice and None should be returned
        self.assertEqual(2, mocked_callback.call_count,
                         'The callback should have been called twice')
        self.assertIsNone(result,
                          'The get_song() method should have returned None')
コード例 #18
0
    def test_login_succeeds(self, MockedBeautifulSoup, mocked_build_opener):
        """
        Test that when logging in to SongSelect succeeds, the login method returns True
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        mocked_opener = MagicMock()
        mocked_build_opener.return_value = mocked_opener
        mocked_login_page = MagicMock()
        mocked_login_page.find.side_effect = [{'value': 'blah'}, MagicMock()]
        MockedBeautifulSoup.return_value = mocked_login_page
        mock_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: The login method is called after being rigged to fail
        result = importer.login('username', 'password', mock_callback)

        # THEN: callback was called 3 times, open was called twice, find was called twice, and True was returned
        self.assertEqual(3, mock_callback.call_count,
                         'callback should have been called 3 times')
        self.assertEqual(2, mocked_login_page.find.call_count,
                         'find should have been called twice')
        self.assertEqual(2, mocked_opener.open.call_count,
                         'opener should have been called twice')
        self.assertTrue(result, 'The login method should have returned True')
コード例 #19
0
ファイル: test_songselect.py プロジェクト: jkunle/paul
    def search_reaches_max_results_test(self, MockedBeautifulSoup,
                                        mocked_build_opener):
        """
        Test that when the search finds MAX (2) results, it simply returns a list with those (2)
        """
        # GIVEN: A bunch of mocked out stuff and an importer object
        # first search result
        mocked_result1 = MagicMock()
        mocked_result1.find.side_effect = [
            MagicMock(string='Title 1'), {
                'href': '/url1'
            }
        ]
        mocked_result1.find_all.return_value = [
            MagicMock(string='Author 1-1'),
            MagicMock(string='Author 1-2')
        ]
        # second search result
        mocked_result2 = MagicMock()
        mocked_result2.find.side_effect = [
            MagicMock(string='Title 2'), {
                'href': '/url2'
            }
        ]
        mocked_result2.find_all.return_value = [
            MagicMock(string='Author 2-1'),
            MagicMock(string='Author 2-2')
        ]
        # third search result
        mocked_result3 = MagicMock()
        mocked_result3.find.side_effect = [
            MagicMock(string='Title 3'), {
                'href': '/url3'
            }
        ]
        mocked_result3.find_all.return_value = [
            MagicMock(string='Author 3-1'),
            MagicMock(string='Author 3-2')
        ]
        # rest of the stuff
        mocked_opener = MagicMock()
        mocked_build_opener.return_value = mocked_opener
        mocked_results_page = MagicMock()
        mocked_results_page.find_all.side_effect = [[
            mocked_result1, mocked_result2, mocked_result3
        ], []]
        MockedBeautifulSoup.return_value = mocked_results_page
        mock_callback = MagicMock()
        importer = SongSelectImport(None)

        # WHEN: The login method is called after being rigged to fail
        results = importer.search('text', 2, mock_callback)

        # THEN: callback was never called, open was called once, find_all was called once, an empty list returned
        self.assertEqual(2, mock_callback.call_count,
                         'callback should have been called twice')
        self.assertEqual(2, mocked_opener.open.call_count,
                         'open should have been called twice')
        self.assertEqual(2, mocked_results_page.find_all.call_count,
                         'find_all should have been called twice')
        mocked_results_page.find_all.assert_called_with('li', 'result pane')
        expected_list = [{
            'title': 'Title 1',
            'authors': ['Author 1-1', 'Author 1-2'],
            'link': BASE_URL + '/url1'
        }, {
            'title': 'Title 2',
            'authors': ['Author 2-1', 'Author 2-2'],
            'link': BASE_URL + '/url2'
        }]
        self.assertListEqual(
            expected_list, results,
            'The search method should have returned two songs')