diff --git a/SafeExamBrowser.Contracts/Logging/ILogger.cs b/SafeExamBrowser.Contracts/Logging/ILogger.cs index 8b4979ce..352f5a2f 100644 --- a/SafeExamBrowser.Contracts/Logging/ILogger.cs +++ b/SafeExamBrowser.Contracts/Logging/ILogger.cs @@ -16,37 +16,44 @@ namespace SafeExamBrowser.Contracts.Logging /// /// Logs the given message with severity INFO. /// + /// void Info(string message); /// /// Logs the given message with severity WARNING. /// + /// void Warn(string message); /// /// Logs the given message with severity ERROR. /// + /// void Error(string message); /// /// Logs the given message with severity ERROR and includes information about /// the specified exception (i.e. type, message and stacktrace). /// + /// void Error(string message, Exception exception); /// /// Logs the given message as raw text. /// + /// void Log(string message); /// /// Appends the given content to the log. /// + /// void Log(ILogContent content); /// /// Suscribes an observer to the application log. /// + /// void Subscribe(ILogObserver observer); /// diff --git a/SafeExamBrowser.Core.UnitTests/Logging/DefaultLogFormatterTests.cs b/SafeExamBrowser.Core.UnitTests/Logging/DefaultLogFormatterTests.cs new file mode 100644 index 00000000..1610b5b2 --- /dev/null +++ b/SafeExamBrowser.Core.UnitTests/Logging/DefaultLogFormatterTests.cs @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using SafeExamBrowser.Contracts.Logging; +using SafeExamBrowser.Core.Logging; + +namespace SafeExamBrowser.Core.UnitTests.Logging +{ + [TestClass] + public class DefaultLogFormatterTests + { + [TestMethod] + [ExpectedException(typeof(NotImplementedException))] + public void MustReportNotYetImplementedLogContent() + { + var sut = new DefaultLogFormatter(); + + sut.Format(new NewLogContentType()); + } + + [TestMethod] + public void MustReturnRawTextForLogMessage() + { + var sut = new DefaultLogFormatter(); + var entry = new LogText("Must return this text..."); + + var text = sut.Format(entry); + + Assert.AreEqual(entry.Text, text); + } + + [TestMethod] + public void MustCorrectlyFormatLogMessage() + { + var sut = new DefaultLogFormatter(); + var date = new DateTime(2017, 10, 10, 15, 24, 38); + var threadInfo = new ThreadInfo(1234, "ABC"); + var entry = new LogMessage(date, LogLevel.Warning, "Here's a warning message...", threadInfo); + + var text = sut.Format(entry); + + Assert.AreEqual($"2017-10-10 15:24:38.000 [1234: ABC] - WARNING: Here's a warning message...", text); + } + } +} diff --git a/SafeExamBrowser.Core.UnitTests/Logging/LoggerTests.cs b/SafeExamBrowser.Core.UnitTests/Logging/LoggerTests.cs index 23f08876..4dcda524 100644 --- a/SafeExamBrowser.Core.UnitTests/Logging/LoggerTests.cs +++ b/SafeExamBrowser.Core.UnitTests/Logging/LoggerTests.cs @@ -67,6 +67,19 @@ namespace SafeExamBrowser.Core.UnitTests.Logging } } + [TestMethod] + public void MustNotAllowLoggingNull() + { + var sut = new Logger(); + + Assert.ThrowsException(() => sut.Info(null)); + Assert.ThrowsException(() => sut.Warn(null)); + Assert.ThrowsException(() => sut.Error(null)); + Assert.ThrowsException(() => sut.Error(null, null)); + Assert.ThrowsException(() => sut.Log((string) null)); + Assert.ThrowsException(() => sut.Log((ILogContent) null)); + } + [TestMethod] [ExpectedException(typeof(ArgumentNullException))] public void MustNotAllowNullObserver() diff --git a/SafeExamBrowser.Core.UnitTests/Logging/ModuleLoggerTests.cs b/SafeExamBrowser.Core.UnitTests/Logging/ModuleLoggerTests.cs new file mode 100644 index 00000000..44bcd05d --- /dev/null +++ b/SafeExamBrowser.Core.UnitTests/Logging/ModuleLoggerTests.cs @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using SafeExamBrowser.Contracts.Logging; +using SafeExamBrowser.Core.Logging; + +namespace SafeExamBrowser.Core.UnitTests.Logging +{ + [TestClass] + public class ModuleLoggerTests + { + [TestMethod] + public void MustCorrectlyForwardCalls() + { + var loggerMock = new Mock(); + var logObserverMock = new Mock(); + var logText = new LogText("Log text"); + var sut = new ModuleLogger(loggerMock.Object, typeof(ModuleLoggerTests)); + + sut.Info("Info"); + sut.Warn("Warning"); + sut.Error("Error"); + sut.Log("Raw text"); + sut.Log(logText); + sut.Subscribe(logObserverMock.Object); + sut.Unsubscribe(logObserverMock.Object); + sut.GetLog(); + + loggerMock.Verify(l => l.Info($"[{nameof(ModuleLoggerTests)}] Info"), Times.Once); + loggerMock.Verify(l => l.Warn($"[{nameof(ModuleLoggerTests)}] Warning"), Times.Once); + loggerMock.Verify(l => l.Error($"[{nameof(ModuleLoggerTests)}] Error"), Times.Once); + loggerMock.Verify(l => l.Log("Raw text"), Times.Once); + loggerMock.Verify(l => l.Log(logText), Times.Once); + loggerMock.Verify(l => l.Subscribe(logObserverMock.Object), Times.Once); + loggerMock.Verify(l => l.Unsubscribe(logObserverMock.Object), Times.Once); + loggerMock.Verify(l => l.GetLog(), Times.Once); + } + } +} diff --git a/SafeExamBrowser.Core.UnitTests/Logging/NewLogContentType.cs b/SafeExamBrowser.Core.UnitTests/Logging/NewLogContentType.cs new file mode 100644 index 00000000..c56912ca --- /dev/null +++ b/SafeExamBrowser.Core.UnitTests/Logging/NewLogContentType.cs @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2017 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using SafeExamBrowser.Contracts.Logging; + +namespace SafeExamBrowser.Core.UnitTests.Logging +{ + class NewLogContentType : ILogContent + { + public object Clone() + { + throw new NotImplementedException(); + } + } +} diff --git a/SafeExamBrowser.Core.UnitTests/SafeExamBrowser.Core.UnitTests.csproj b/SafeExamBrowser.Core.UnitTests/SafeExamBrowser.Core.UnitTests.csproj index f0ab8304..3f26e552 100644 --- a/SafeExamBrowser.Core.UnitTests/SafeExamBrowser.Core.UnitTests.csproj +++ b/SafeExamBrowser.Core.UnitTests/SafeExamBrowser.Core.UnitTests.csproj @@ -77,7 +77,10 @@ + + + diff --git a/SafeExamBrowser.Core/Logging/LogMessage.cs b/SafeExamBrowser.Core/Logging/LogMessage.cs index a39d6cf4..e463c1c4 100644 --- a/SafeExamBrowser.Core/Logging/LogMessage.cs +++ b/SafeExamBrowser.Core/Logging/LogMessage.cs @@ -9,9 +9,9 @@ using System; using SafeExamBrowser.Contracts.Logging; -namespace SafeExamBrowser.Core.Entities +namespace SafeExamBrowser.Core.Logging { - class LogMessage : ILogMessage + public class LogMessage : ILogMessage { public DateTime DateTime { get; private set; } public LogLevel Severity { get; private set; } diff --git a/SafeExamBrowser.Core/Logging/Logger.cs b/SafeExamBrowser.Core/Logging/Logger.cs index 7e65fa76..25a8137b 100644 --- a/SafeExamBrowser.Core/Logging/Logger.cs +++ b/SafeExamBrowser.Core/Logging/Logger.cs @@ -12,7 +12,6 @@ using System.Linq; using System.Text; using System.Threading; using SafeExamBrowser.Contracts.Logging; -using SafeExamBrowser.Core.Entities; namespace SafeExamBrowser.Core.Logging { @@ -24,21 +23,46 @@ namespace SafeExamBrowser.Core.Logging public void Info(string message) { + if (message == null) + { + throw new ArgumentNullException(nameof(message)); + } + Add(LogLevel.Info, message); } public void Warn(string message) { + if (message == null) + { + throw new ArgumentNullException(nameof(message)); + } + Add(LogLevel.Warning, message); } public void Error(string message) { + if (message == null) + { + throw new ArgumentNullException(nameof(message)); + } + Add(LogLevel.Error, message); } public void Error(string message, Exception exception) { + if (message == null) + { + throw new ArgumentNullException(nameof(message)); + } + + if (exception == null) + { + throw new ArgumentNullException(nameof(exception)); + } + var details = new StringBuilder(); details.AppendLine(); diff --git a/SafeExamBrowser.Core/Logging/ThreadInfo.cs b/SafeExamBrowser.Core/Logging/ThreadInfo.cs index d7b7a666..43b6d088 100644 --- a/SafeExamBrowser.Core/Logging/ThreadInfo.cs +++ b/SafeExamBrowser.Core/Logging/ThreadInfo.cs @@ -11,7 +11,7 @@ using SafeExamBrowser.Contracts.Logging; namespace SafeExamBrowser.Core.Logging { - class ThreadInfo : IThreadInfo + public class ThreadInfo : IThreadInfo { public int Id { get; private set; } public string Name { get; private set; }