class_name FakeHttpTransport extends HttpTransport ## Stands in for the MusicServer in tests. ## ## Register canned responses per path with [method respond_json] or ## [method respond_bytes], then install it with [method install]. Requests to paths ## without a response get a 404. Responses are delivered immediately. ## Paths requested so far, relative to [code]Settings.default_path[/code]. var requested_paths: Array[String] = [] ## HTTP method of each request, in the same order as [member requested_paths]. var requested_methods: Array[int] = [] var _responses: Dictionary = {} var _successes_left: Dictionary = {} var _held_paths: Dictionary = {} var _previous_transport: HttpTransport func _init() -> void: super(null) ## Replaces the MusicServerClient transport with this fake. func install() -> FakeHttpTransport: _previous_transport = MusicServerClient.transport MusicServerClient.transport = self return self ## Restores the transport that was active before [method install]. func uninstall() -> void: MusicServerClient.transport = _previous_transport ## Answers requests to [param path] with [param data] encoded as JSON. func respond_json(path: String, data: Variant, response_code: int = 200) -> void: respond_bytes(path, JSON.stringify(data).to_utf8_buffer(), response_code) ## Answers requests to [param path] with [param body] as-is. func respond_bytes(path: String, body: PackedByteArray, response_code: int = 200) -> void: _responses[path] = {"code": response_code, "body": body} _successes_left.erase(path) ## Lets [param successes] more requests to [param path] succeed, then answers 503 until ## a new response is registered for the path. func fail_after(path: String, successes: int) -> void: _successes_left[path] = successes ## Holds back responses to [param path] until [method release] is called, like a slow ## server. func hold(path: String) -> void: _held_paths[path] = [] ## Delivers the responses held back for [param path] and stops holding it. func release(path: String) -> void: var waiting: Array = _held_paths.get(path, []) _held_paths.erase(path) for pending: Callable in waiting: pending.call() ## Returns how many times [param path] has been requested. func count(path: String) -> int: return requested_paths.count(path) func request(url: String, method: int, on_complete: Callable) -> void: var path: String = url.trim_prefix(Settings.default_path) requested_paths.append(path) requested_methods.append(method) if _held_paths.has(path): _held_paths[path].append(_answer.bind(path, on_complete)) return _answer(path, on_complete) func _answer(path: String, on_complete: Callable) -> void: if _successes_left.has(path): if _successes_left[path] == 0: on_complete.call(503, PackedByteArray()) return _successes_left[path] -= 1 if _responses.has(path): on_complete.call(_responses[path].code, _responses[path].body) else: on_complete.call(404, PackedByteArray())