songs2slides

A tool that automatically finds song lyrics and creates lyric slideshows
git clone https://git.ashermorgan.net/songs2slides/
Log | Files | Refs | README

test_routes.py (8052B)


      1 import pytest
      2 
      3 from songs2slides import create_app, core, routes
      4 
      5 @pytest.fixture(autouse=True)
      6 def client():
      7     app = create_app()
      8     return app.test_client()
      9 
     10 def test_get_lyrics_basic(client, mocker):
     11     # Mock get_song_data, parse_song_lyrics, and render_template
     12     mocker.patch('songs2slides.core.get_song_data')
     13     mocker.patch('songs2slides.core.parse_song_lyrics')
     14     mocker.patch('songs2slides.routes.render_template')
     15     songs = [
     16         core.SongData('T1', 'A1', 'L1'),
     17         core.SongData('T2', 'A2', 'L2'),
     18     ]
     19     core.get_song_data.side_effect = songs
     20     core.parse_song_lyrics.side_effect = ['L1', 'L2']
     21 
     22     # Send request
     23     client.post('/create/step-2/', data={
     24         'title-1': 'T1',
     25         'artist-1': 'A1',
     26         'title-2': 'T2',
     27         'artist-2': 'A2',
     28     })
     29 
     30     # Assert mocks called correctly
     31     core.get_song_data.assert_has_calls([
     32         mocker.call('T1', 'A1'), mocker.call('T2', 'A2')
     33     ])
     34     core.parse_song_lyrics.assert_has_calls([
     35         mocker.call('L1', 4), mocker.call('L2', 4)
     36     ])
     37     routes.render_template.assert_called_with('create-step-2.html', songs=songs,
     38                                               missing=0, api_error=False)
     39 
     40 def test_get_lyrics_one_error(client, mocker):
     41     # Mock get_song_data, parse_song_lyrics, and render_template
     42     mocker.patch('songs2slides.core.get_song_data')
     43     mocker.patch('songs2slides.core.parse_song_lyrics')
     44     mocker.patch('songs2slides.routes.render_template')
     45     songs = [
     46         core.SongData('T1', 'A1', None),
     47         core.SongData('T2', 'A2', 'L2'),
     48     ]
     49     core.get_song_data.side_effect = [Exception(), songs[1]]
     50     core.parse_song_lyrics.side_effect = ['L1', 'L2']
     51 
     52     # Send request
     53     client.post('/create/step-2/', data={
     54         'title-1': 'T1',
     55         'artist-1': 'A1',
     56         'title-2': 'T2',
     57         'artist-2': 'A2',
     58     })
     59 
     60     # Assert mocks called correctly
     61     core.get_song_data.assert_has_calls([
     62         mocker.call('T1', 'A1'), mocker.call('T2', 'A2')
     63     ])
     64     core.parse_song_lyrics.assert_has_calls([mocker.call('L2', 4)])
     65     routes.render_template.assert_called_with('create-step-2.html', songs=songs,
     66                                               missing=1, api_error=False)
     67 
     68 def test_get_lyrics_missing_artist(client, mocker):
     69     # Mock get_song_data
     70     mocker.patch('songs2slides.core.get_song_data')
     71 
     72     # Send request
     73     res = client.post('/create/step-2/', data={
     74         'title-1': 'T1',
     75         'title-2': 'T2',
     76         'artist-2': 'A2',
     77     })
     78 
     79     # Assert mocks not called
     80     core.get_song_data.assert_not_called()
     81 
     82     # Assert response has 400 status code
     83     assert res.status_code == 400
     84 
     85 def test_update_lyrics(client, mocker):
     86     # Mock render_template
     87     mocker.patch('songs2slides.routes.render_template')
     88 
     89     # Send request
     90     client.post('/create/step-3/', data={
     91         'title-1': 'T1',
     92         'artist-1': 'A1',
     93         'lyrics-1': 'L1',
     94         'title-2': 'T2',
     95         'artist-2': 'A2',
     96         'lyrics-2': 'L2',
     97         'output-type': 'html',
     98         'title-slides': 'on',
     99     })
    100 
    101     # Assert render_template called correctly
    102     routes.render_template.assert_called_with('create-step-3.html', songs=[
    103         core.SongData('T1', 'A1', 'L1'),
    104         core.SongData('T2', 'A2', 'L2'),
    105     ])
    106 
    107 def test_create_slides_basic(client, mocker):
    108     # Mock assemble_slides, create_pptx, and send_file
    109     mocker.patch('songs2slides.core.assemble_slides')
    110     mocker.patch('songs2slides.core.create_pptx')
    111     mocker.patch('songs2slides.routes.send_file')
    112 
    113     # Send request
    114     client.post('/slides/', data={
    115         'title-1': 'T1',
    116         'artist-1': 'A1',
    117         'lyrics-1': 'L1',
    118         'title-2': 'T2',
    119         'artist-2': 'A2',
    120         'lyrics-2': 'L2',
    121         'output-type': 'pptx',
    122         'title-slides': 'on',
    123         'blank-slides': 'on',
    124     })
    125 
    126     # Assert mocks called correctly
    127     core.assemble_slides.assert_called_with([
    128             core.SongData('T1', 'A1', 'L1'),
    129             core.SongData('T2', 'A2', 'L2'),
    130         ],
    131         lines_per_slide = None,
    132         title_slides = True,
    133         blank_slides = True,
    134     )
    135     file = core.create_pptx.call_args.args[1]
    136     routes.send_file.assert_called_with(file, as_attachment=True,
    137                                    download_name='slides.pptx')
    138 
    139 def test_create_slides_mising_artist(client, mocker):
    140     # Mock assemble_slides
    141     mocker.patch('songs2slides.core.assemble_slides')
    142 
    143     # Send request
    144     res = client.post('/slides/', data={
    145         'title-1': 'T1',
    146         'artist-1': 'A1',
    147         'lyrics-1': 'L1',
    148         'title-2': 'T2',
    149         'lyrics-2': 'L2',
    150         'output-type': 'pptx',
    151         'title-slides': 'on',
    152         'blank-slides': 'on',
    153     })
    154 
    155     # Assert response has 400 status code
    156     assert res.status_code == 400
    157 
    158     # Assert assemble_slides not called
    159     core.assemble_slides.assert_not_called()
    160 
    161 def test_create_slides_html_slides(client, mocker):
    162     # Mock assemble_slides, create_pptx, render_template
    163     mocker.patch('songs2slides.core.assemble_slides')
    164     mocker.patch('songs2slides.core.create_pptx')
    165     mocker.patch('songs2slides.routes.render_template')
    166     slides = ['T1', 'L1\nL2', 'L3', 'T2', 'L4']
    167     core.assemble_slides.return_value = slides
    168 
    169     # Send request
    170     client.post('/slides/', data={
    171         'title-1': 'T1',
    172         'artist-1': 'A1',
    173         'lyrics-1': 'L1',
    174         'title-2': 'T2',
    175         'artist-2': 'A2',
    176         'lyrics-2': 'L2',
    177         'output-type': 'html',
    178         'title-slides': 'on',
    179         'blank-slides': 'on',
    180     })
    181 
    182     # Assert mocks called correctly
    183     core.assemble_slides.assert_called_with([
    184             core.SongData('T1', 'A1', 'L1'),
    185             core.SongData('T2', 'A2', 'L2'),
    186         ],
    187         lines_per_slide = None,
    188         title_slides = True,
    189         blank_slides = True,
    190     )
    191     core.create_pptx.assert_not_called()
    192     routes.render_template.assert_called_with('slides.html', slides=slides)
    193 
    194 def test_create_slides_no_title_slides(client, mocker):
    195     # Mock assemble_slides, create_pptx, render_template
    196     mocker.patch('songs2slides.core.assemble_slides')
    197     mocker.patch('songs2slides.core.create_pptx')
    198     mocker.patch('songs2slides.routes.render_template')
    199     slides = ['T1', 'L1\nL2', 'L3', 'T2', 'L4']
    200     core.assemble_slides.return_value = slides
    201 
    202     # Send request
    203     client.post('/slides/', data={
    204         'title-1': 'T1',
    205         'artist-1': 'A1',
    206         'lyrics-1': 'L1',
    207         'title-2': 'T2',
    208         'artist-2': 'A2',
    209         'lyrics-2': 'L2',
    210         'output-type': 'html',
    211         'blank-slides': 'on',
    212     })
    213 
    214     # Assert mocks called correctly
    215     core.assemble_slides.assert_called_with([
    216             core.SongData('T1', 'A1', 'L1'),
    217             core.SongData('T2', 'A2', 'L2'),
    218         ],
    219         lines_per_slide = None,
    220         title_slides = False,
    221         blank_slides = True,
    222     )
    223     core.create_pptx.assert_not_called()
    224     routes.render_template.assert_called_with('slides.html', slides=slides)
    225 
    226 def test_create_slides_no_blank_slides(client, mocker):
    227     # Mock assemble_slides, create_pptx, render_template
    228     mocker.patch('songs2slides.core.assemble_slides')
    229     mocker.patch('songs2slides.core.create_pptx')
    230     mocker.patch('songs2slides.routes.render_template')
    231     slides = ['T1', 'L1\nL2', 'L3', 'T2', 'L4']
    232     core.assemble_slides.return_value = slides
    233 
    234     # Send request
    235     client.post('/slides/', data={
    236         'title-1': 'T1',
    237         'artist-1': 'A1',
    238         'lyrics-1': 'L1',
    239         'title-2': 'T2',
    240         'artist-2': 'A2',
    241         'lyrics-2': 'L2',
    242         'output-type': 'html',
    243         'title-slides': 'on',
    244     })
    245 
    246     # Assert mocks called correctly
    247     core.assemble_slides.assert_called_with([
    248             core.SongData('T1', 'A1', 'L1'),
    249             core.SongData('T2', 'A2', 'L2'),
    250         ],
    251         lines_per_slide = None,
    252         title_slides = True,
    253         blank_slides = False,
    254     )
    255     core.create_pptx.assert_not_called()
    256     routes.render_template.assert_called_with('slides.html', slides=slides)