// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Threading; using System.Threading.Tasks; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Users; namespace osu.Game.Online.API { public class DummyAPIAccess : Component, IAPIProvider { public Bindable LocalUser { get; } = new Bindable(new User { Username = @"Dummy", Id = 1001, }); public BindableList Friends { get; } = new BindableList(); public Bindable Activity { get; } = new Bindable(); public string AccessToken => "token"; public bool IsLoggedIn => State.Value == APIState.Online; public string ProvidedUsername => LocalUser.Value.Username; public string APIEndpointUrl => "http://localhost"; public string WebsiteRootUrl => "http://localhost"; public Exception LastLoginError { get; private set; } /// /// Provide handling logic for an arbitrary API request. /// Should return true is a request was handled. If null or false return, the request will be failed with a . /// public Func HandleRequest; private readonly Bindable state = new Bindable(APIState.Online); private bool shouldFailNextLogin; /// /// The current connectivity state of the API. /// public IBindable State => state; public DummyAPIAccess() { LocalUser.BindValueChanged(u => { u.OldValue?.Activity.UnbindFrom(Activity); u.NewValue.Activity.BindTo(Activity); }, true); } public virtual void Queue(APIRequest request) { if (HandleRequest?.Invoke(request) != true) { // this will fail due to not receiving an APIAccess, and trigger a failure on the request. // this is intended - any request in testing that needs non-failures should use HandleRequest. request.Perform(this); } } public void Perform(APIRequest request) => HandleRequest?.Invoke(request); public Task PerformAsync(APIRequest request) { HandleRequest?.Invoke(request); return Task.CompletedTask; } public void Login(string username, string password) { state.Value = APIState.Connecting; if (shouldFailNextLogin) { LastLoginError = new APIException("Not powerful enough to login.", new ArgumentException(nameof(shouldFailNextLogin))); state.Value = APIState.Offline; shouldFailNextLogin = false; return; } LastLoginError = null; LocalUser.Value = new User { Username = username, Id = 1001, }; state.Value = APIState.Online; } public void Logout() { LocalUser.Value = new GuestUser(); state.Value = APIState.Offline; } public IHubClientConnector GetHubConnector(string clientName, string endpoint, bool preferMessagePack) => null; public RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password) { Thread.Sleep(200); return null; } public void SetState(APIState newState) => state.Value = newState; IBindable IAPIProvider.LocalUser => LocalUser; IBindableList IAPIProvider.Friends => Friends; IBindable IAPIProvider.Activity => Activity; public void FailNextLogin() => shouldFailNextLogin = true; } }