extends MainWindowTestSuite ## Adding a soundtrack from a folder: picked in the statistics or dropped on the window, ## uploaded one song at a time, and found everywhere afterwards. const UPLOADS: String = "/soundtracks/uploads" const UPLOAD_ID: String = "0b5e2b1e-3a4f-4d5e-9f00-000000000001" var _popup: UploadPopup var _dir: String func before_test() -> void: await super() _popup = _window.get_node("UploadPopup") _dir = create_temp_dir("upload_%d" % randi()).path_join("Chrono Trigger") _song("01 Title.mp3", "ID3 title") _song("Disc 2/01 Ending.mp3", "ID3 ending") _song("02 Theme.flac", "flac") func after_test() -> void: Settings.currently_syncing = false await super() func _song(relative: String, content: String) -> void: var path: String = _dir.path_join(relative) DirAccess.make_dir_recursive_absolute(path.get_base_dir()) var file: FileAccess = FileAccess.open(path, FileAccess.WRITE) file.store_string(content) file.close() func _file_path(file_name: String) -> String: return "%s/%s/files/%s" % [UPLOADS, UPLOAD_ID, file_name.uri_encode()] func _server_accepts_everything() -> void: _server.respond_json(UPLOADS, {"id": UPLOAD_ID, "name": "Chrono Trigger", "files": []}, 201) _server.respond_json(_file_path("01 Title.mp3"), {"name": "01 Title.mp3", "size": 9}) _server.respond_json(_file_path("01 Ending.mp3"), {"name": "01 Ending.mp3", "size": 10}) _server.respond_json("%s/%s/finish" % [UPLOADS, UPLOAD_ID], {"uuid": "st-new", "name": "Chrono Trigger", "songs": [{"name": "01 Title"}, {"name": "01 Ending"}]}) _server.respond_bytes("%s/%s" % [UPLOADS, UPLOAD_ID], PackedByteArray(), 204) func _upload_requests() -> Array[String]: var paths: Array[String] = [] for path: String in _server.requested_paths: if path.begins_with(UPLOADS): paths.append(path) return paths func test_folder_lists_its_songs_and_what_is_left_out() -> void: _popup.show_folder(_dir) assert_bool(_popup.visible).is_true() assert_str(_popup.name_field.text).is_equal("Chrono Trigger") assert_int(_popup.song_list.get_child_count()).is_equal(3) assert_str(_popup.summary_label.text).starts_with("2 songs, ") assert_str(_popup.summary_label.text).contains("1 file left out") assert_bool(_popup.upload_button.disabled).is_false() func test_upload_sends_each_song_then_finishes() -> void: _server_accepts_everything() var added: Array[String] = [] _popup.soundtrack_added.connect( func(soundtrack: SoundtrackWithSongList) -> void: added.append(soundtrack.name)) var searches_before: int = _server.count("/soundtracks") _popup.show_folder(_dir) _popup.name_field.text = "Chrono Trigger (SNES)" _popup.upload() assert_array(_upload_requests()).contains_exactly([UPLOADS, _file_path("01 Title.mp3"), _file_path("01 Ending.mp3"), "%s/%s/finish" % [UPLOADS, UPLOAD_ID]]) var start: int = _server.requested_paths.find(UPLOADS) assert_str(JSON.parse_string(_server.requested_bodies[start]).name) \ .is_equal("Chrono Trigger (SNES)") var first_song: int = _server.requested_paths.find(_file_path("01 Title.mp3")) assert_int(_server.requested_methods[first_song]).is_equal(HTTPClient.METHOD_PUT) assert_str(_server.requested_bodies[first_song]).is_equal("ID3 title") assert_array(_server.requested_headers[first_song]).contains(["Content-Type: audio/mpeg"]) assert_array(added).contains_exactly(["Chrono Trigger"]) assert_str(_popup.status_label.text).is_equal("Added Chrono Trigger with 2 songs.") assert_bool(_popup.upload_button.visible).is_false() assert_str(_popup.cancel_button.text).is_equal("Close") # Search finds the new soundtrack assert_int(_server.count("/soundtracks")).is_greater(searches_before) func test_song_that_fails_once_is_sent_again() -> void: _server_accepts_everything() _server.fail_first(_file_path("01 Title.mp3"), 1) _popup.show_folder(_dir) _popup.upload() assert_int(_server.count(_file_path("01 Title.mp3"))).is_equal(2) assert_int(_server.count("%s/%s/finish" % [UPLOADS, UPLOAD_ID])).is_equal(1) func test_song_that_keeps_failing_cancels_the_upload() -> void: _server_accepts_everything() _server.respond_json(_file_path("01 Title.mp3"), {"error": "\"01 Title.mp3\" is not an MP3 file"}, 400) _popup.show_folder(_dir) _popup.upload() assert_int(_server.count(_file_path("01 Title.mp3"))).is_equal(UploadPopup.RETRIES + 1) var cancel: int = _server.requested_paths.find("%s/%s" % [UPLOADS, UPLOAD_ID]) assert_int(_server.requested_methods[cancel]).is_equal(HTTPClient.METHOD_DELETE) assert_int(_server.count("%s/%s/finish" % [UPLOADS, UPLOAD_ID])).is_equal(0) assert_str(_popup.status_label.text).is_equal( "Could not upload 01 Title.mp3: \"01 Title.mp3\" is not an MP3 file.") assert_bool(_popup.upload_button.disabled).is_false() func test_taken_name_says_so() -> void: _server.respond_json(UPLOADS, {"error": "already exists: a soundtrack called \"Chrono Trigger\""}, 409) _popup.show_folder(_dir) _popup.upload() assert_str(_popup.status_label.text).contains("a soundtrack called \"Chrono Trigger\"") assert_array(_upload_requests()).contains_exactly([UPLOADS]) assert_bool(_popup.name_field.editable).is_true() func test_closing_during_the_upload_cancels_it() -> void: _server_accepts_everything() _server.hold(_file_path("01 Title.mp3")) _popup.show_folder(_dir) _popup.upload() _popup.close() _server.release(_file_path("01 Title.mp3")) assert_int(_server.count("%s/%s" % [UPLOADS, UPLOAD_ID])).is_equal(1) assert_int(_server.count(_file_path("01 Ending.mp3"))).is_equal(0) func test_no_upload_while_the_server_syncs() -> void: Settings.currently_syncing = true _popup.show_folder(_dir) _popup.upload() assert_array(_upload_requests()).is_empty() assert_str(_popup.status_label.text).contains("syncing") func test_folder_without_mp3s_cannot_be_uploaded() -> void: var empty: String = _dir.get_base_dir().path_join("Empty") DirAccess.make_dir_recursive_absolute(empty) _popup.show_folder(empty) assert_bool(_popup.upload_button.disabled).is_true() assert_str(_popup.status_label.text).contains("no MP3 files") func test_empty_name_cannot_be_uploaded() -> void: _popup.show_folder(_dir) _popup.name_field.text = " .. " _popup.name_field.text_changed.emit(_popup.name_field.text) assert_bool(_popup.upload_button.disabled).is_true() func test_dropping_a_folder_opens_it() -> void: _window.on_files_dropped(PackedStringArray([_dir])) assert_bool(_popup.visible).is_true() assert_str(_popup.folder.path).is_equal(_dir) func test_dropping_songs_opens_their_folder() -> void: _window.on_files_dropped(PackedStringArray([_dir.path_join("01 Title.mp3")])) assert_str(_popup.folder.path).is_equal(_dir) func test_statistics_has_the_button() -> void: var statistics: StatisticsView = _window.get_node("StatisticsView") assert_bool(statistics.add_soundtrack_pressed.is_connected(_popup.choose_folder)).is_true() assert_str(statistics.add_soundtrack_button.text).is_equal("Add soundtrack…") @warning_ignore("unused_parameter") func test_short_path(path: String, shown: String, test_parameters: Array = [ ["/home/me/Music/Chrono Trigger", "…/Music/Chrono Trigger"], ["C:\\Music\\Soundtracks\\Chrono Trigger", "…/Soundtracks/Chrono Trigger"], ["/Music", "/Music"], ]) -> void: assert_str(UploadPopup.short_path(path)).is_equal(shown)