public void EmptyConstructor()
        {
            var ui = new UserIndex();

            Assert.NotNull(ui.Data);
            Assert.Empty(ui.Data);
        }
        public void SetIndex()
        {
            var index = new UserIndex().UpdateTimestamp("user1", UnixMillisecondTime.OfMillis(1000));

            _wrapper.SetIndex(index);

            var serializedData = _persistentStore.GetValue(ExpectedEnvironmentNamespace, ExpectedIndexKey);

            AssertJsonEqual(index.Serialize(), serializedData);
        }
        public void Deserialize()
        {
            var json = @"[[""user1"",1000],[""user2"",2000]]";
            var ui   = UserIndex.Deserialize(json);

            Assert.NotNull(ui.Data);
            Assert.Collection(ui.Data,
                              AssertEntry("user1", 1000),
                              AssertEntry("user2", 2000));
        }
        public void Serialize()
        {
            var ui = new UserIndex()
                     .UpdateTimestamp("user1", UnixMillisecondTime.OfMillis(1000))
                     .UpdateTimestamp("user2", UnixMillisecondTime.OfMillis(2000));

            var json     = ui.Serialize();
            var expected = @"[[""user1"",1000],[""user2"",2000]]";

            AssertJsonEqual(expected, json);
        }
        public void PruneWhenLimitIsNotExceeded()
        {
            var ui = new UserIndex()
                     .UpdateTimestamp("user1", UnixMillisecondTime.OfMillis(1000))
                     .UpdateTimestamp("user2", UnixMillisecondTime.OfMillis(2000));

            Assert.Same(ui, ui.Prune(3, out var removed1));
            Assert.Empty(removed1);

            Assert.Same(ui, ui.Prune(2, out var removed2));
            Assert.Empty(removed2);
        }
        public void UpdateTimestampForExistingUser()
        {
            var ui = new UserIndex()
                     .UpdateTimestamp("user1", UnixMillisecondTime.OfMillis(1000))
                     .UpdateTimestamp("user2", UnixMillisecondTime.OfMillis(2000));

            ui = ui.UpdateTimestamp("user1", UnixMillisecondTime.OfMillis(2001));

            Assert.Collection(ui.Data,
                              AssertEntry("user2", 2000),
                              AssertEntry("user1", 2001));
        }
        public void PruneRemovesLeastRecentUsers()
        {
            var ui = new UserIndex()
                     .UpdateTimestamp("user1", UnixMillisecondTime.OfMillis(1000))
                     .UpdateTimestamp("user2", UnixMillisecondTime.OfMillis(2000))
                     .UpdateTimestamp("user3", UnixMillisecondTime.OfMillis(1111)) // deliberately out of order
                     .UpdateTimestamp("user4", UnixMillisecondTime.OfMillis(3000))
                     .UpdateTimestamp("user5", UnixMillisecondTime.OfMillis(4000));

            var ui1 = ui.Prune(3, out var removed);

            Assert.Equal(ImmutableList.Create("user1", "user3"), removed);
            Assert.Collection(ui1.Data,
                              AssertEntry("user2", 2000),
                              AssertEntry("user4", 3000),
                              AssertEntry("user5", 4000));
        }
        public void DeserializeMalformedJson()
        {
            Assert.ThrowsAny <FormatException>(() =>
                                               UserIndex.Deserialize("}"));

            Assert.ThrowsAny <FormatException>(() =>
                                               UserIndex.Deserialize("["));

            Assert.ThrowsAny <FormatException>(() =>
                                               UserIndex.Deserialize("[[true,1000]]"));

            Assert.ThrowsAny <FormatException>(() =>
                                               UserIndex.Deserialize(@"[[""user1"",false]]"));

            Assert.ThrowsAny <FormatException>(() =>
                                               UserIndex.Deserialize("[3]"));
        }
        public UserIndex GetIndex()
        {
            string data = HandleErrorsAndLock(() => _persistentStore.GetValue(_environmentNamespace, EnvironmentMetadataKey));

            if (data is null)
            {
                return(new UserIndex());
            }
            try
            {
                return(UserIndex.Deserialize(data));
            }
            catch (Exception)
            {
                _log.Warn("Discarding invalid data from persistent store index");
                return(new UserIndex());
            }
        }
 public void SetIndex(UserIndex index) =>
 HandleErrorsAndLock(() => _persistentStore.SetValue(_environmentNamespace, EnvironmentMetadataKey, index.Serialize()));