< Summary

Class:UserProfile
Assembly:UserProfile
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/UserProfile/UserProfile.cs
Covered lines:69
Uncovered lines:23
Coverable lines:92
Total lines:187
Line coverage:75% (69 of 92)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
UserProfile()0%110100%
UpdateData(...)0%6.046089.29%
GetItemAmount(...)0%330100%
OverrideAvatar(...)0%220100%
SetAvatarExpression(...)0%440100%
SetInventory(...)0%440100%
AddToInventory(...)0%6200%
RemoveFromInventory(...)0%2100%
ContainsInInventory(...)0%2100%
GetInventoryItemsIds()0%2100%
GetOwnUserProfile()0%220100%
CloneModel()0%2100%
IsBlocked(...)0%220100%
Block(...)0%2.062075%
Unblock(...)0%2100%
HasEquipped(...)0%2100%
OnEnable()0%110100%
CleanUp()0%6200%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/UserProfile/UserProfile.cs

#LineLine coverage
 1using DCL;
 2using DCL.Helpers;
 3using Decentraland.Renderer.KernelServices;
 4using System;
 5using System.Collections.Generic;
 6using System.Linq;
 7using UnityEditor;
 8using UnityEngine;
 9using Environment = DCL.Environment;
 10
 11[CreateAssetMenu(fileName = "UserProfile", menuName = "UserProfile")]
 12public class UserProfile : ScriptableObject //TODO Move to base variable
 13{
 14    public enum EmoteSource
 15    {
 16        EmotesWheel,
 17        Shortcut,
 18        Command,
 19        Backpack
 20    }
 21
 22    public event Action<UserProfile> OnUpdate;
 23    public event Action<string, long, EmoteSource> OnAvatarEmoteSet;
 24
 52525    public string userId => model.userId;
 5326    public string ethAddress => model.ethAddress;
 21827    public string userName => model.name;
 3228    public string description => model.description;
 029    public string email => model.email;
 030    public string bodySnapshotURL => model.ComposeCorrectUrl(model.snapshots.body);
 15031    public string face256SnapshotURL => model.ComposeCorrectUrl(model.snapshots.face256);
 032    public string baseUrl => model.baseUrl;
 033    public UserProfileModel.ParcelsWithAccess[] parcelsWithAccess => model.parcelsWithAccess;
 19834    public List<string> blocked => model.blocked != null ? model.blocked : new List<string>();
 435    public List<string> muted => model.muted ?? new List<string>();
 21336    public bool hasConnectedWeb3 => model.hasConnectedWeb3;
 5337    public bool hasClaimedName => model.hasClaimedName;
 2038    public bool isGuest => !model.hasConnectedWeb3;
 73739    public AvatarModel avatar => model.avatar;
 040    public int tutorialStep => model.tutorialStep;
 41
 65442    internal Dictionary<string, int> inventory = new Dictionary<string, int>();
 43
 65444    public ILazyTextureObserver snapshotObserver = new LazyTextureObserver();
 65445    public ILazyTextureObserver bodySnapshotObserver = new LazyTextureObserver();
 46
 65447    internal UserProfileModel model = new UserProfileModel() //Empty initialization to avoid nullchecks
 48    {
 49        avatar = new AvatarModel()
 50    };
 51
 65452    private int emoteLamportTimestamp = 1;
 53
 54    public void UpdateData(UserProfileModel newModel)
 55    {
 65356        if (newModel == null)
 57        {
 058            model = new UserProfileModel();
 059            return;
 60        }
 61
 65362        bool isModelDirty = !newModel.Equals(model);
 65363        bool faceSnapshotDirty = model.snapshots.face256 != newModel.snapshots.face256;
 65364        bool bodySnapshotDirty = model.snapshots.body != newModel.snapshots.body;
 65
 65366        model.userId = newModel.userId;
 65367        model.ethAddress = newModel.ethAddress;
 65368        model.parcelsWithAccess = newModel.parcelsWithAccess;
 65369        model.tutorialStep = newModel.tutorialStep;
 65370        model.hasClaimedName = newModel.hasClaimedName;
 65371        model.name = newModel.name;
 65372        model.email = newModel.email;
 65373        model.description = newModel.description;
 65374        model.baseUrl = newModel.baseUrl;
 65375        model.avatar.CopyFrom(newModel.avatar);
 65376        model.snapshots = newModel.snapshots;
 65377        model.hasConnectedWeb3 = newModel.hasConnectedWeb3;
 65378        model.blocked = newModel.blocked;
 65379        model.muted = newModel.muted;
 65380        model.version = newModel.version;
 81
 65382        if (model.snapshots != null && faceSnapshotDirty)
 3383            snapshotObserver.RefreshWithUri(face256SnapshotURL);
 84
 65385        if (model.snapshots != null && bodySnapshotDirty)
 086            bodySnapshotObserver.RefreshWithUri(bodySnapshotURL);
 87
 65388        if (isModelDirty)
 63289            OnUpdate?.Invoke(this);
 5690    }
 91
 92    public int GetItemAmount(string itemId)
 93    {
 467594        if (inventory == null || !inventory.ContainsKey(itemId))
 463795            return 0;
 96
 3897        return inventory[itemId];
 98    }
 99
 100    public void OverrideAvatar(AvatarModel newModel, Texture2D newFaceSnapshot)
 101    {
 1102        model.avatar.CopyFrom(newModel);
 1103        this.snapshotObserver.RefreshWithTexture(newFaceSnapshot);
 104
 1105        OnUpdate?.Invoke(this);
 1106    }
 107
 108    public void SetAvatarExpression(string id, EmoteSource source)
 109    {
 1110        int timestamp = emoteLamportTimestamp++;
 1111        avatar.expressionTriggerId = id;
 1112        avatar.expressionTriggerTimestamp = timestamp;
 113
 1114        ClientEmotesKernelService emotes = Environment.i.serviceLocator.Get<IRPC>().Emotes();
 115        // TODO: fix message `Timestamp` should NOT be `float`, we should use `int lamportTimestamp` or `long timeStamp`
 1116        emotes?.TriggerExpression(new TriggerExpressionRequest()
 117        {
 118            Id = id,
 119            Timestamp = timestamp
 120        });
 121
 1122        OnUpdate?.Invoke(this);
 1123        OnAvatarEmoteSet?.Invoke(id, timestamp, source);
 1124    }
 125
 126    public void SetInventory(string[] inventoryIds)
 127    {
 206128        inventory.Clear();
 2867129        inventory = inventoryIds.GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count());
 206130    }
 131
 132    public void AddToInventory(string wearableId)
 133    {
 0134        if (inventory.ContainsKey(wearableId))
 0135            inventory[wearableId]++;
 136        else
 0137            inventory.Add(wearableId, 1);
 0138    }
 139
 0140    public void RemoveFromInventory(string wearableId) { inventory.Remove(wearableId); }
 141
 0142    public bool ContainsInInventory(string wearableId) => inventory.ContainsKey(wearableId);
 143
 0144    public string[] GetInventoryItemsIds() { return inventory.Keys.ToArray(); }
 145
 146    internal static UserProfile ownUserProfile;
 147
 148    public static UserProfile GetOwnUserProfile()
 149    {
 2818150        if (ownUserProfile == null)
 151        {
 19152            ownUserProfile = Resources.Load<UserProfile>("ScriptableObjects/OwnUserProfile");
 153        }
 154
 2818155        return ownUserProfile;
 156    }
 157
 0158    public UserProfileModel CloneModel() => model.Clone();
 159
 62160    public bool IsBlocked(string userId) { return blocked != null && blocked.Contains(userId); }
 161
 162    public void Block(string userId)
 163    {
 19164        if (IsBlocked(userId))
 0165            return;
 19166        blocked.Add(userId);
 19167    }
 168
 0169    public void Unblock(string userId) { blocked.Remove(userId); }
 170
 0171    public bool HasEquipped(string wearableId) => avatar.wearables.Contains(wearableId);
 172
 173#if UNITY_EDITOR
 174    private void OnEnable()
 175    {
 654176        Application.quitting -= CleanUp;
 654177        Application.quitting += CleanUp;
 654178    }
 179
 180    private void CleanUp()
 181    {
 0182        Application.quitting -= CleanUp;
 0183        if (AssetDatabase.Contains(this))
 0184            Resources.UnloadAsset(this);
 0185    }
 186#endif
 187}