test_core.py (11095B)
1 import pytest 2 3 from songs2slides import core 4 5 def test_filter_lyrics_inline(): 6 # Declare raw lyrics and expected cleaned lyrics 7 lyrics = 'A[remove]B\nC(remove)D' 8 expected = 'AB\nCD' 9 10 # Clean lyrics 11 result = core.filter_lyrics(lyrics) 12 13 # Assert slides are correct 14 assert result == expected 15 16 def test_filter_lyrics_whole_lines(): 17 # Declare raw lyrics and expected cleaned lyrics 18 lyrics = 'A\n[remove]\nB\n(remove)\nC' 19 expected = 'A\nB\nC' 20 21 # Clean lyrics 22 result = core.filter_lyrics(lyrics) 23 24 # Assert slides are correct 25 assert result == expected 26 27 def test_filter_lyrics_multiple_lines(): 28 # Declare raw lyrics and expected cleaned lyrics 29 lyrics = 'A\n[re\nmove]\nB\n(re\nmove)\nC' 30 expected = 'A\nB\nC' 31 32 # Clean lyrics 33 result = core.filter_lyrics(lyrics) 34 35 # Assert slides are correct 36 assert result == expected 37 38 def test_filter_lyrics_blank_lines(): 39 # Declare raw lyrics and expected cleaned lyrics 40 lyrics = 'A\n[remove]\n\n(remove)\nB' 41 expected = 'A\n\nB' 42 43 # Clean lyrics 44 result = core.filter_lyrics(lyrics) 45 46 # Assert slides are correct 47 assert result == expected 48 49 def test_filter_lyrics_all(): 50 # Declare raw lyrics and expected cleaned lyrics 51 lyrics = 'A[remove]B\n[remove]\n\nC(remove)D\n(re\nmove)' 52 expected = 'AB\n\nCD' 53 54 # Clean lyrics 55 result = core.filter_lyrics(lyrics) 56 57 # Assert slides are correct 58 assert result == expected 59 60 def test_filter_lyrics_empty_string(): 61 # Clean lyrics 62 result = core.filter_lyrics('') 63 64 # Assert slides are correct 65 assert result == '' 66 67 def test_get_song_data_success(mocker): 68 # Mock os.getenv, requests.get, and filter_lyrics 69 mocker.patch('songs2slides.core.os.getenv') 70 mocker.patch('songs2slides.core.requests.get') 71 mocker.patch('songs2slides.core.filter_lyrics') 72 core.os.getenv.side_effect = [ 73 'api://lyrics/{artist}/{title}', 74 'Bearer secrettoken' 75 ] 76 core.requests.get.return_value.json.return_value = { 77 'lyrics': 'raw', 78 'title': 'Foo', 79 'artist': 'Bar', 80 } 81 core.requests.get.return_value.status_code = 200 82 core.filter_lyrics.return_value = 'clean' 83 84 # Get song data 85 song_data = core.get_song_data('foo', 'bar') 86 87 # Assert mocked methods were used correctly 88 core.os.getenv.assert_has_calls([ 89 mocker.call('API_URL'), 90 mocker.call('API_AUTH', None) 91 ]) 92 core.requests.get.assert_called_with('api://lyrics/bar/foo', headers={ 93 'Authorization': 'Bearer secrettoken' 94 }) 95 core.filter_lyrics.assert_called_with('raw') 96 97 # Assert song data is correct 98 assert song_data.title == 'Foo' 99 assert song_data.artist == 'Bar' 100 assert song_data.lyrics == 'clean' 101 102 def test_get_song_data_no_auth_header(mocker): 103 # Mock os.getenv, requests.get, and filter_lyrics 104 mocker.patch('songs2slides.core.os.getenv') 105 mocker.patch('songs2slides.core.requests.get') 106 mocker.patch('songs2slides.core.filter_lyrics') 107 core.os.getenv.side_effect = [ 108 'api://lyrics/{artist}/{title}', 109 None, 110 ] 111 core.requests.get.return_value.json.return_value = { 112 'lyrics': 'raw', 113 'title': 'Foo', 114 'artist': 'Bar', 115 } 116 core.requests.get.return_value.status_code = 200 117 core.filter_lyrics.return_value = 'clean' 118 119 # Get song data 120 song_data = core.get_song_data('foo', 'bar') 121 122 # Assert mocked methods were used correctly 123 core.os.getenv.assert_has_calls([ 124 mocker.call('API_URL'), 125 mocker.call('API_AUTH', None) 126 ]) 127 core.requests.get.assert_called_with('api://lyrics/bar/foo', headers={}) 128 core.filter_lyrics.assert_called_with('raw') 129 130 # Assert song data is correct 131 assert song_data.title == 'Foo' 132 assert song_data.artist == 'Bar' 133 assert song_data.lyrics == 'clean' 134 135 def test_get_song_data_no_url(mocker): 136 # Mock os.getenv and requests.get 137 mocker.patch('songs2slides.core.os.getenv') 138 mocker.patch('songs2slides.core.requests.get') 139 core.os.getenv.return_value = None 140 core.requests.get.return_value.text = b'{}' 141 core.requests.get.return_value.status_code = 200 142 143 # Try to get song data 144 with pytest.raises(Exception): 145 song_data = core.get_song_data('foo', 'bar') 146 147 # Assert request was not called 148 core.requests.get.assert_not_called() 149 150 def test_get_song_data_not_found(mocker): 151 # Mock os.getenv and requests.get 152 mocker.patch('songs2slides.core.os.getenv') 153 mocker.patch('songs2slides.core.requests.get') 154 core.os.getenv.side_effect = [ 155 'api://lyrics/{artist}/{title}', 156 'Bearer secrettoken' 157 ] 158 core.requests.get.return_value.text = b'{}' 159 core.requests.get.return_value.status_code = 200 160 161 # Try to get song data 162 with pytest.raises(Exception): 163 song_data = core.get_song_data('foo', 'bar') 164 165 # Assert request was called 166 core.requests.get.assert_called_with('api://lyrics/bar/foo', headers={ 167 'Authorization': 'Bearer secrettoken' 168 }) 169 170 def test_parse_song_lyrics_basic(): 171 # Declare song data and expected slides 172 lyrics = 'A\nB\nC\nD\nE\nF\n\nG\nH' 173 expected = ['A\nB\nC\nD', 'E\nF', 'G\nH'] 174 175 # Get slide content 176 result = core.parse_song_lyrics(lyrics, 4) 177 178 # Assert slides are correct 179 assert result == expected 180 181 def test_parse_song_lyrics_3_lines_per_slide(): 182 # Declare song data and expected slides 183 lyrics = 'A\nB\nC\nD\nE\nF\n\nG\nH' 184 expected = ['A\nB\nC', 'D\nE\nF', 'G\nH'] 185 186 # Get slide content 187 result = core.parse_song_lyrics(lyrics, 3) 188 189 # Assert slides are correct 190 assert result == expected 191 192 def test_parse_song_lyrics_empty_string(): 193 # Declare song data and expected slides 194 lyrics = '' 195 expected = [] 196 197 # Get slide content 198 result = core.parse_song_lyrics(lyrics, 4) 199 200 # Assert slides are correct 201 assert result == expected 202 203 def test_parse_song_lyrics_one_line(): 204 # Declare song data and expected slides 205 lyrics = 'A' 206 expected = ['A'] 207 208 # Get slide content 209 result = core.parse_song_lyrics(lyrics, 4) 210 211 # Assert slides are correct 212 assert result == expected 213 214 def test_parse_song_lyrics_one_slide(): 215 # Declare song data and expected slides 216 lyrics = 'A\nB\nC\nD' 217 expected = ['A\nB\nC\nD'] 218 219 # Get slide content 220 result = core.parse_song_lyrics(lyrics, 4) 221 222 # Assert slides are correct 223 assert result == expected 224 225 def test_parse_song_lyrics_tripple_newlines(): 226 # Declare song data and expected slides 227 lyrics = 'A\nB\n\n\nC\nD' 228 expected = ['A\nB', '', 'C\nD'] 229 230 # Get slide content 231 result = core.parse_song_lyrics(lyrics, 4) 232 233 # Assert slides are correct 234 assert result == expected 235 236 def test_parse_song_lyrics_extra_whitespace(): 237 # Declare song data and expected slides 238 lyrics = ' A\n B \nC D\nE ' 239 expected = ['A\nB\nC D\nE'] 240 241 # Get slide content 242 result = core.parse_song_lyrics(lyrics, 4) 243 244 # Assert slides are correct 245 assert result == expected 246 247 def test_parse_song_lyrics_extra_newlines(): 248 # Declare song data and expected slides 249 lyrics = '\n\n\nA\n\n\n\n\nB\n\n\n' 250 expected = ['A', '', 'B'] 251 252 # Get slide content 253 result = core.parse_song_lyrics(lyrics, 4) 254 255 # Assert slides are correct 256 assert result == expected 257 258 def test_assemble_slides_calls_parse_song_lyrics(mocker): 259 # Mock parse_song_lyrics 260 mocker.patch('songs2slides.core.parse_song_lyrics') 261 core.parse_song_lyrics.side_effect = [['aaa'], ['b1', 'b2']] 262 263 # Declare song data and expected slides 264 songs = [ 265 core.SongData('T1', 'A1', 'l1'), 266 core.SongData('T2', 'A3', 'l2'), 267 ] 268 expected = ['T1', 'aaa', '', 'T2', 'b1', 'b2'] 269 270 # Get slides 271 slides = core.assemble_slides(songs) 272 273 # Assert slides are correct 274 assert slides == expected 275 276 # Assert parse_song_lyrics called 277 core.parse_song_lyrics.assert_has_calls([ 278 mocker.call('L1', 4), mocker.call('L2', 4) 279 ]) 280 281 def test_assemble_slides_default(): 282 # Declare song data and expected slides 283 songs = [ 284 core.SongData('t1', 'a1', 'l1\nl2\nl3\nl4\nl5'), 285 core.SongData('T2', 'A3', 'L6\nL7\n\nL8\n\n\nL9'), 286 ] 287 expected = [ 288 'T1', 'L1\nL2\nL3\nL4', 'L5', '', 289 'T2', 'L6\nL7', 'L8', '', 'L9', 290 ] 291 292 # Get slides 293 slides = core.assemble_slides(songs) 294 295 # Assert slides are correct 296 assert slides == expected 297 298 def test_assemble_slides_custom_lines_per_slide(mocker): 299 # Mock parse_song_lyrics 300 mocker.patch('songs2slides.core.parse_song_lyrics') 301 core.parse_song_lyrics.side_effect = [['aaa'], ['b1', 'b2']] 302 303 # Declare song data and expected slides 304 songs = [ 305 core.SongData('T1', 'A1', 'l1'), 306 core.SongData('T2', 'A3', 'l2'), 307 ] 308 expected = ['T1', 'aaa', '', 'T2', 'b1', 'b2'] 309 310 # Get slides 311 slides = core.assemble_slides(songs, lines_per_slide = 3) 312 313 # Assert slides are correct 314 assert slides == expected 315 316 # Assert parse_song_lyrics called correctly 317 core.parse_song_lyrics.assert_has_calls([ 318 mocker.call('L1', 3), mocker.call('L2', 3) 319 ]) 320 321 def test_assemble_slides_no_title_slides(): 322 # Declare song data and expected slides 323 songs = [ 324 core.SongData('t1', 'a1', 'l1\nl2\nl3\nl4\nl5'), 325 core.SongData('T2', 'A3', 'L6\nL7\n\nL8\n\n\nL9'), 326 ] 327 expected = [ 328 'L1\nL2\nL3\nL4', 'L5', '', 329 'L6\nL7', 'L8', '', 'L9', 330 ] 331 332 # Get slides 333 slides = core.assemble_slides(songs, title_slides = False) 334 335 # Assert slides are correct 336 assert slides == expected 337 338 def test_assemble_slides_no_blank_slides(): 339 # Declare song data and expected slides 340 songs = [ 341 core.SongData('t1', 'a1', 'l1\nl2\nl3\nl4\nl5'), 342 core.SongData('T2', 'A3', 'L6\nL7\n\nL8\n\n\nL9'), 343 ] 344 expected = [ 345 'T1', 'L1\nL2\nL3\nL4', 'L5', 346 'T2', 'L6\nL7', 'L8', '', 'L9', 347 ] 348 349 # Get slides 350 slides = core.assemble_slides(songs, blank_slides = False) 351 352 # Assert slides are correct 353 assert slides == expected 354 355 def test_assemble_slides_no_extra_slides(): 356 # Declare song data and expected slides 357 songs = [ 358 core.SongData('t1', 'a1', 'l1\nl2\nl3\nl4\nl5'), 359 core.SongData('T2', 'A3', 'L6\nL7\n\nL8\n\n\nL9'), 360 ] 361 expected = [ 362 'L1\nL2\nL3\nL4', 'L5', 363 'L6\nL7', 'L8', '', 'L9', 364 ] 365 366 # Get slides 367 slides = core.assemble_slides(songs, title_slides = False, blank_slides = False) 368 369 # Assert slides are correct 370 assert slides == expected 371 372 def test_assemble_slides_no_songs(): 373 # Declare expected slides 374 expected = [] 375 376 # Get slides 377 slides = core.assemble_slides([]) 378 379 # Assert slides are correct 380 assert slides == expected 381 382 def test_create_pptx(mocker): 383 # Mock Presentation.save 384 mocker.patch('songs2slides.core.pptx.presentation.Presentation.save') 385 386 # Create PowerPoint 387 core.create_pptx(['A', 'B\nC', 'D'], 'test.pptx') 388 389 # Assert PowerPoint was saved 390 core.pptx.presentation.Presentation.save.assert_called_with('test.pptx')