diff --git a/Parse.Tests/AnalyticsTests.cs b/Parse.Tests/AnalyticsTests.cs index 43eae776..730fa8f1 100644 --- a/Parse.Tests/AnalyticsTests.cs +++ b/Parse.Tests/AnalyticsTests.cs @@ -13,14 +13,46 @@ namespace Parse.Tests; [TestClass] public class AnalyticsTests { -#warning Skipped post-test-evaluation cleaning method may be needed. - // [TestCleanup] - // public void TearDown() => (Client.Services as ServiceHub).Reset(); + private Mock _mockAnalyticsController; + private Mock _mockCurrentUserController; + private MutableServiceHub _hub; + private ParseClient _client; + + + [TestInitialize] + public void Initialize() + { + _mockAnalyticsController = new Mock(); + _mockCurrentUserController = new Mock(); + + _mockCurrentUserController + .Setup(controller => controller.GetCurrentSessionTokenAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync("sessionToken"); + + + _hub = new MutableServiceHub + { + AnalyticsController = _mockAnalyticsController.Object, + CurrentUserController = _mockCurrentUserController.Object + }; + _client = new ParseClient(new ServerConnectionData { Test = true }, _hub); + } + + [TestCleanup] + public void Cleanup() + { + _mockAnalyticsController = null; + _mockCurrentUserController = null; + _hub = null; + _client = null; + } + [TestMethod] public async Task TestTrackEvent() { + // Arrange var hub = new MutableServiceHub(); var client = new ParseClient(new ServerConnectionData { Test = true }, hub); diff --git a/Parse.Tests/CloudControllerTests.cs b/Parse.Tests/CloudControllerTests.cs index f25da4ac..c26a5863 100644 --- a/Parse.Tests/CloudControllerTests.cs +++ b/Parse.Tests/CloudControllerTests.cs @@ -1,3 +1,4 @@ + using System; using System.Collections.Generic; using System.Net; @@ -13,30 +14,48 @@ namespace Parse.Tests; -#warning Class refactoring requires completion. - [TestClass] public class CloudControllerTests { - ParseClient Client { get; set; } + private Mock _mockRunner; + private ParseCloudCodeController _cloudCodeController; + private ParseClient Client { get; set; } [TestInitialize] - public void SetUp() => Client = new ParseClient(new ServerConnectionData { ApplicationID = "", Key = "", Test = true }); + public void SetUp() + { + Client = new ParseClient(new ServerConnectionData { ApplicationID = "", Key = "", Test = true }); + _mockRunner = new Mock(); + } + + [TestCleanup] + public void Cleanup() + { + _mockRunner = null; + _cloudCodeController = null; + Client = null; + } + [TestMethod] public async Task TestEmptyCallFunction() { - // Arrange: Create a mock runner that simulates a response with an accepted status but no data - var mockRunner = CreateMockRunner( - new Tuple>(HttpStatusCode.Accepted, null) - ); + // Arrange: Setup mock runner and controller + + _mockRunner.Setup(obj => obj.RunCommandAsync( + It.IsAny(), + It.IsAny>(), + It.IsAny>(), + It.IsAny() + )).Returns(Task.FromResult(new Tuple>(HttpStatusCode.Accepted, null))); + + _cloudCodeController = new ParseCloudCodeController(_mockRunner.Object, Client.Decoder); - var controller = new ParseCloudCodeController(mockRunner.Object, Client.Decoder); // Act & Assert: Call the function and verify the task faults as expected try { - await controller.CallFunctionAsync("someFunction", null, null, Client, CancellationToken.None); + await _cloudCodeController.CallFunctionAsync("someFunction", null, null, Client, CancellationToken.None); Assert.Fail("Expected the task to fault, but it succeeded."); } catch (ParseFailureException ex) @@ -44,22 +63,26 @@ public async Task TestEmptyCallFunction() Assert.AreEqual(ParseFailureException.ErrorCode.OtherCause, ex.Code); Assert.AreEqual("Cloud function returned no data.", ex.Message); } - } [TestMethod] public async Task TestCallFunction() { - // Arrange: Create a mock runner with a predefined response + // Arrange: Setup mock runner and controller with a response var responseDict = new Dictionary { ["result"] = "gogo" }; - var response = new Tuple>(HttpStatusCode.Accepted, responseDict); - var mockRunner = CreateMockRunner(response); + _mockRunner.Setup(obj => obj.RunCommandAsync( + It.IsAny(), + It.IsAny>(), + It.IsAny>(), + It.IsAny() + )).Returns(Task.FromResult(new Tuple>(HttpStatusCode.Accepted, responseDict))); + + _cloudCodeController = new ParseCloudCodeController(_mockRunner.Object, Client.Decoder); - var cloudCodeController = new ParseCloudCodeController(mockRunner.Object, Client.Decoder); // Act: Call the function and capture the result - var result = await cloudCodeController.CallFunctionAsync( + var result = await _cloudCodeController.CallFunctionAsync( "someFunction", parameters: null, sessionToken: null, @@ -76,24 +99,29 @@ public async Task TestCallFunction() [TestMethod] public async Task TestCallFunctionWithComplexType() { - // Arrange: Create a mock runner with a complex type response + // Arrange: Setup mock runner and controller with a complex type response var complexResponse = new Dictionary { { "result", new Dictionary - { - { "fosco", "ben" }, - { "list", new List { 1, 2, 3 } } - } + { + { "fosco", "ben" }, + { "list", new List { 1, 2, 3 } } + } } }; - var mockRunner = CreateMockRunner( - new Tuple>(HttpStatusCode.Accepted, complexResponse) - ); - var cloudCodeController = new ParseCloudCodeController(mockRunner.Object, Client.Decoder); + _mockRunner.Setup(obj => obj.RunCommandAsync( + It.IsAny(), + It.IsAny>(), + It.IsAny>(), + It.IsAny() + )).Returns(Task.FromResult(new Tuple>(HttpStatusCode.Accepted, complexResponse))); + + _cloudCodeController = new ParseCloudCodeController(_mockRunner.Object, Client.Decoder); + // Act: Call the function with a complex return type - var result = await cloudCodeController.CallFunctionAsync>( + var result = await _cloudCodeController.CallFunctionAsync>( "someFunction", parameters: null, sessionToken: null, @@ -107,25 +135,32 @@ public async Task TestCallFunctionWithComplexType() Assert.AreEqual("ben", result["fosco"]); Assert.IsInstanceOfType(result["list"], typeof(IList)); } + [TestMethod] public async Task TestCallFunctionWithWrongType() { // a mock runner with a response that doesn't match the expected type + var wrongTypeResponse = new Dictionary - { - { "result", "gogo" } - }; - var mockRunner = CreateMockRunner( - new Tuple>(HttpStatusCode.Accepted, wrongTypeResponse) - ); + { + { "result", "gogo" } + }; + + _mockRunner.Setup(obj => obj.RunCommandAsync( + It.IsAny(), + It.IsAny>(), + It.IsAny>(), + It.IsAny() + )).Returns(Task.FromResult(new Tuple>(HttpStatusCode.Accepted, wrongTypeResponse))); - var cloudCodeController = new ParseCloudCodeController(mockRunner.Object, Client.Decoder); + + _cloudCodeController = new ParseCloudCodeController(_mockRunner.Object, Client.Decoder); // Act & Assert: Expect the call to fail with a ParseFailureException || This is fun! await Assert.ThrowsExceptionAsync(async () => { - await cloudCodeController.CallFunctionAsync( + await _cloudCodeController.CallFunctionAsync( "someFunction", parameters: null, sessionToken: null, @@ -134,20 +169,4 @@ await cloudCodeController.CallFunctionAsync( ); }); } - - - - private Mock CreateMockRunner(Tuple> response) - { - var mockRunner = new Mock(); - mockRunner.Setup(obj => obj.RunCommandAsync( - It.IsAny(), - It.IsAny>(), - It.IsAny>(), - It.IsAny() - )).Returns(Task.FromResult(response)); - - return mockRunner; - } - -} +} \ No newline at end of file diff --git a/Parse.Tests/CloudTests.cs b/Parse.Tests/CloudTests.cs index 601a3fca..3348934a 100644 --- a/Parse.Tests/CloudTests.cs +++ b/Parse.Tests/CloudTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Net; using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -19,80 +20,78 @@ namespace Parse.Tests; [TestClass] public class CloudTests { -#warning Skipped post-test-evaluation cleaning method may be needed. + private Mock _commandRunnerMock; + private Mock _decoderMock; + private MutableServiceHub _hub; + private ParseClient _client; - // [TestCleanup] - // public void TearDown() => ParseCorePlugins.Instance.Reset(); - [TestMethod] - public async Task TestCloudFunctionsMissingResultAsync() + [TestInitialize] + public void Initialize() { - // Arrange - var commandRunnerMock = new Mock(); - var decoderMock = new Mock(); + _commandRunnerMock = new Mock(); + _decoderMock = new Mock(); + } + + [TestCleanup] + public void Cleanup() + { + _commandRunnerMock = null; + _decoderMock = null; + _hub = null; + _client = null; + + } + + - // Mock CommandRunner - commandRunnerMock + private void SetupMocksForMissingResult() + { + _commandRunnerMock .Setup(runner => runner.RunCommandAsync( It.IsAny(), It.IsAny>(), It.IsAny>(), It.IsAny() )) - .ReturnsAsync(new Tuple>( - System.Net.HttpStatusCode.OK, + .ReturnsAsync(new Tuple>( + HttpStatusCode.OK, new Dictionary { ["unexpectedKey"] = "unexpectedValue" // Missing "result" key })); - // Mock Decoder - decoderMock + _decoderMock .Setup(decoder => decoder.Decode(It.IsAny(), It.IsAny())) .Returns(new Dictionary { ["unexpectedKey"] = "unexpectedValue" }); + } + + + + [TestMethod] + public async Task TestCloudFunctionsMissingResultAsync() + { + // Arrange + SetupMocksForMissingResult(); - // Set up service hub - var hub = new MutableServiceHub + _hub = new MutableServiceHub { - CommandRunner = commandRunnerMock.Object, - CloudCodeController = new ParseCloudCodeController(commandRunnerMock.Object, decoderMock.Object) + CommandRunner = _commandRunnerMock.Object, + CloudCodeController = new ParseCloudCodeController(_commandRunnerMock.Object, _decoderMock.Object) }; - var client = new ParseClient(new ServerConnectionData { Test = true }, hub); + _client = new ParseClient(new ServerConnectionData { Test = true }, _hub); // Act & Assert await Assert.ThrowsExceptionAsync(async () => - await client.CallCloudCodeFunctionAsync>("someFunction", null, CancellationToken.None)); + await _client.CallCloudCodeFunctionAsync>("someFunction", null, CancellationToken.None)); } [TestMethod] public async Task TestParseCloudCodeControllerMissingResult() { - // Arrange - var commandRunnerMock = new Mock(); - var decoderMock = new Mock(); - - // Mock the CommandRunner response - commandRunnerMock - .Setup(runner => runner.RunCommandAsync( - It.IsAny(), - It.IsAny>(), - It.IsAny>(), - It.IsAny() - )) - .ReturnsAsync(new Tuple>( - System.Net.HttpStatusCode.OK, // Simulated HTTP status code - new Dictionary - { - ["unexpectedKey"] = "unexpectedValue" // Missing "result" key - })); - - // Mock the Decoder response - decoderMock - .Setup(decoder => decoder.Decode(It.IsAny(), It.IsAny())) - .Returns(new Dictionary { ["unexpectedKey"] = "unexpectedValue" }); - - // Initialize the controller - var controller = new ParseCloudCodeController(commandRunnerMock.Object, decoderMock.Object); + //Arrange + SetupMocksForMissingResult(); + var controller = new ParseCloudCodeController(_commandRunnerMock.Object, _decoderMock.Object); // Act & Assert await Assert.ThrowsExceptionAsync(async () => @@ -103,7 +102,4 @@ await controller.CallFunctionAsync>( null, CancellationToken.None)); } - - - -} +} \ No newline at end of file diff --git a/Parse.Tests/ConfigTests.cs b/Parse.Tests/ConfigTests.cs index 37a98c69..c93eeb8d 100644 --- a/Parse.Tests/ConfigTests.cs +++ b/Parse.Tests/ConfigTests.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -5,9 +6,12 @@ using Moq; using Newtonsoft.Json; using Parse.Abstractions.Infrastructure; +using Parse.Abstractions.Infrastructure.Data; +using Parse.Abstractions.Infrastructure.Execution; using Parse.Abstractions.Platform.Configuration; using Parse.Abstractions.Platform.Users; using Parse.Infrastructure; +using Parse.Infrastructure.Execution; using Parse.Platform.Configuration; namespace Parse.Tests @@ -61,7 +65,8 @@ public void SetUp() => public void TearDown() => ((Client.Services as OrchestrationServiceHub).Default as ServiceHub).Reset(); [TestMethod] - public async void TestCurrentConfig() + [Description("Tests TestCurrentConfig Returns the right config")] + public async Task TestCurrentConfig()// Mock difficulty: 1 { var config = await Client.GetCurrentConfiguration(); @@ -70,7 +75,8 @@ public async void TestCurrentConfig() } [TestMethod] - public async void TestToJSON() + [Description("Tests the conversion of properties to json objects")] + public async Task TestToJSON() // Mock difficulty: 1 { var expectedJson = new Dictionary { @@ -81,8 +87,10 @@ public async void TestToJSON() Assert.AreEqual(JsonConvert.SerializeObject(expectedJson), JsonConvert.SerializeObject(actualJson)); } + [TestMethod] - public async Task TestGetConfigAsync() + [Description("Tests the fetching of a new config with an IServiceHub instance.")] + public async Task TestGetConfigAsync()// Mock difficulty: 1 { var config = await Client.GetConfigurationAsync(); @@ -91,7 +99,8 @@ public async Task TestGetConfigAsync() } [TestMethod] - public async Task TestGetConfigCancelAsync() + [Description("Tests fetching of config is cancelled when requested via a cancellation token.")] + public async Task TestGetConfigCancelAsync() // Mock difficulty: 1 { var tokenSource = new CancellationTokenSource(); tokenSource.Cancel(); @@ -102,4 +111,37 @@ await Assert.ThrowsExceptionAsync(async () => }); } } -} + [TestClass] + public class ParseConfigurationTests + { + + //[TestMethod] + //[Description("Tests that Get method throws an exception if key is not found")] + //public void Get_ThrowsExceptionNotFound() // Mock difficulty: 1 + //{ + // var services = new Mock().Object; + // ParseConfiguration configuration = new(services); + // Assert.ThrowsException(() => configuration.Get("doesNotExist")); + //} + + + [TestMethod] + [Description("Tests that create function creates correct configuration object")] + public void Create_BuildsConfigurationFromDictionary() // Mock difficulty: 3 + { + var mockDecoder = new Mock(); + var mockServices = new Mock(); + var dict = new Dictionary + { + ["params"] = new Dictionary { { "test", 1 } }, + }; + mockDecoder.Setup(d => d.Decode(It.IsAny(), It.IsAny())).Returns(new Dictionary { { "test", 1 } }); + + var config = ParseConfiguration.Create(dict, mockDecoder.Object, mockServices.Object); + Assert.AreEqual(1, config["test"]); + Assert.IsInstanceOfType(config, typeof(ParseConfiguration)); + } + } + + +} \ No newline at end of file diff --git a/Parse.Tests/InstallationTests.cs b/Parse.Tests/InstallationTests.cs index 196e152b..07713cab 100644 --- a/Parse.Tests/InstallationTests.cs +++ b/Parse.Tests/InstallationTests.cs @@ -234,7 +234,7 @@ public void TestChannelGetterSetter() } [TestMethod] - public async void TestGetCurrentInstallation() + public async Task TestGetCurrentInstallation() { var guid = Guid.NewGuid(); var expectedInstallation = new ParseInstallation(); diff --git a/Parse.Tests/ObjectTests.cs b/Parse.Tests/ObjectTests.cs index 8c2e1fb2..6977e387 100644 --- a/Parse.Tests/ObjectTests.cs +++ b/Parse.Tests/ObjectTests.cs @@ -1,15 +1,22 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.Http; +using System.Net; +using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Parse.Abstractions.Infrastructure; using Parse.Abstractions.Infrastructure.Control; +using Parse.Abstractions.Infrastructure.Data; +using Parse.Abstractions.Infrastructure.Execution; using Parse.Abstractions.Internal; using Parse.Abstractions.Platform.Objects; using Parse.Infrastructure; +using Parse.Infrastructure.Control; +using Parse.Infrastructure.Execution; using Parse.Platform.Objects; namespace Parse.Tests; @@ -22,7 +29,7 @@ class SubClass : ParseObject { } [ParseClassName(nameof(UnregisteredSubClass))] class UnregisteredSubClass : ParseObject { } - private ParseClient Client { get; set; } + private ParseClient Client { get; set; } [TestInitialize] public void SetUp() @@ -31,8 +38,10 @@ public void SetUp() Client = new ParseClient(new ServerConnectionData { Test = true }); Client.Publicize(); // Register the valid classes - Client.AddValidClass(); - Client.AddValidClass(); + Client.RegisterSubclass(typeof(ParseSession)); + Client.RegisterSubclass(typeof(ParseUser)); + + } [TestCleanup] public void TearDown() => (Client.Services as ServiceHub).Reset(); @@ -465,7 +474,6 @@ public void TestGetQuery() Client.ClassController.RemoveClass(typeof(SubClass)); } -#warning Some tests are not implemented. [TestMethod] public void TestIsDataAvailable() @@ -720,6 +728,402 @@ public async Task TestFetch() [TestMethod] public void TestFetchAll() { - + + } + + + #region New Tests + + [TestMethod] + [Description("Tests Bind method attach an IServiceHub object")] + public void Bind_AttachesServiceHubCorrectly() // Mock difficulty: 1 + { + var mockHub = new Mock(); + var obj = new ParseObject("TestClass"); + var bindedObj = obj.Bind(mockHub.Object); + + Assert.AreSame(obj, bindedObj); + Assert.AreSame(mockHub.Object, obj.Services); + } + [TestMethod] + [Description("Tests that accessing ACL returns default values if no ACL is set.")] + public void ACL_ReturnsDefaultValueWhenNotSet() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + Assert.IsNull(obj.ACL); + } + [TestMethod] + [Description("Tests that setting and getting the class name returns the correct value.")] + public void ClassName_ReturnsCorrectValue() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + Assert.AreEqual("TestClass", obj.ClassName); + } + [TestMethod] + [Description("Tests that CreatedAt and UpdatedAt returns null if they are not yet set.")] + public void CreatedAt_UpdatedAt_ReturnNullIfNotSet() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + Assert.IsNull(obj.CreatedAt); + Assert.IsNull(obj.UpdatedAt); + } + + [TestMethod] + [Description("Tests that IsDirty is true after a value is set.")] + public void IsDirty_ReturnsTrueAfterSet() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + Assert.IsTrue(obj.IsDirty); + obj["test"] = "test"; + Assert.IsTrue(obj.IsDirty); + } + + [TestMethod] + [Description("Tests that IsNew is true by default and changed when value is set")] + public void IsNew_ReturnsCorrectValue() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + Assert.IsFalse(obj.IsNew); + obj.IsNew = true; + Assert.IsTrue(obj.IsNew); + } + + [TestMethod] + [Description("Tests that Keys returns a collection of strings.")] + public void Keys_ReturnsCollectionOfKeys() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["test"] = "test"; + Assert.IsTrue(obj.Keys.Contains("test")); + } + + [TestMethod] + [Description("Tests that objectId correctly stores data.")] + public void ObjectId_ReturnsCorrectValue() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj.ObjectId = "testObjectId"; + Assert.AreEqual("testObjectId", obj.ObjectId); + Assert.IsTrue(obj.IsDirty); + } + + [TestMethod] + [Description("Tests the [] indexer get and set operations")] + public void Indexer_GetSetOperations() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + + obj["testKey"] = "testValue"; + Assert.AreEqual("testValue", obj["testKey"]); + + Assert.IsNull(obj["nonexistantKey"]); + } + + [TestMethod] + [Description("Tests the Add method correctly adds keys.")] + public void Add_AddsNewKey() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj.Add("newKey", "value"); + + Assert.AreEqual("value", obj["newKey"]); + Assert.ThrowsException(() => obj.Add("newKey", "value")); + } + [TestMethod] + [Description("Tests that AddRangeToList adds values.")] + public void AddRangeToList_AddsValuesToList() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj.AddRangeToList("testList", new[] { 1, 2, 3 }); + Assert.AreEqual(3, (obj["testList"] as IEnumerable).Count()); + } + + [TestMethod] + [Description("Tests that AddRangeUniqueToList adds unique values.")] + public void AddRangeUniqueToList_AddsUniqueValues() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj.AddRangeUniqueToList("testList", new[] { 1, 2, 1, 3 }); + Assert.AreEqual(3, (obj["testList"] as IEnumerable).Count()); + } + [TestMethod] + [Description("Tests that AddToList adds a value to the list.")] + public void AddToList_AddsValueToList() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj.AddToList("testList", 1); + Assert.AreEqual(1, (obj["testList"] as IEnumerable).Count()); + } + + [TestMethod] + [Description("Tests that AddUniqueToList adds a unique value to the list.")] + public void AddUniqueToList_AddsUniqueValueToList() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj.AddUniqueToList("testList", 1); + obj.AddUniqueToList("testList", 1); + + Assert.AreEqual(1, (obj["testList"] as IEnumerable).Count()); + } + + [TestMethod] + [Description("Tests that ContainsKey returns true if the key exists.")] + public void ContainsKey_ReturnsCorrectly() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["test"] = "test"; + Assert.IsTrue(obj.ContainsKey("test")); + Assert.IsFalse(obj.ContainsKey("nonExistantKey")); + } + + [TestMethod] + [Description("Tests Get method that attempts to convert to a type and throws exceptions")] + public void Get_ReturnsCorrectTypeOrThrows() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["testInt"] = 1; + obj["testString"] = "test"; + + Assert.AreEqual(1, obj.Get("testInt")); + Assert.AreEqual("test", obj.Get("testString")); + Assert.ThrowsException(() => obj.Get("nonExistantKey")); + Assert.ThrowsException(() => obj.Get("testString")); + } + + + + [TestMethod] + [Description("Tests that HasSameId returns correctly")] + public void HasSameId_ReturnsCorrectly() // Mock difficulty: 1 + { + var obj1 = new ParseObject("TestClass", Client.Services); + var obj2 = new ParseObject("TestClass", Client.Services); + var obj3 = new ParseObject("TestClass", Client.Services); + obj2.ObjectId = "testId"; + obj3.ObjectId = "testId"; + + Assert.IsFalse(obj1.HasSameId(obj2)); + Assert.IsTrue(obj2.HasSameId(obj3)); + } + [TestMethod] + [Description("Tests Increment method by 1.")] + public void Increment_IncrementsValueByOne() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["testInt"] = 1; + obj.Increment("testInt"); + Assert.AreEqual(2, obj.Get("testInt")); + } + [TestMethod] + [Description("Tests Increment by long value")] + public void Increment_IncrementsValueByLong() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["testInt"] = 1; + obj.Increment("testInt", 5); + Assert.AreEqual(6, obj.Get("testInt")); + } + + [TestMethod] + [Description("Tests increment by double value.")] + public void Increment_IncrementsValueByDouble() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["testDouble"] = 1.0; + obj.Increment("testDouble", 2.5); + Assert.AreEqual(3.5, obj.Get("testDouble")); + } + + [TestMethod] + [Description("Tests that IsKeyDirty correctly retrieves dirty keys")] + public void IsKeyDirty_ReturnsCorrectly() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + Assert.IsFalse(obj.IsKeyDirty("test")); + obj["test"] = "test"; + Assert.IsTrue(obj.IsKeyDirty("test")); + } + [TestMethod] + [Description("Tests the Remove method from the object")] + public void Remove_RemovesKeyFromObject() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["test"] = "test"; + obj.Remove("test"); + + Assert.IsFalse(obj.ContainsKey("test")); + } + + [TestMethod] + [Description("Tests the Revert method that discards all the changes")] + public void Revert_ClearsAllChanges() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["test"] = "test"; + obj.Revert(); + + Assert.IsFalse(obj.IsKeyDirty("test")); + } + [TestMethod] + [Description("Tests TryGetValue returns correctly.")] + public void TryGetValue_ReturnsCorrectly() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["test"] = 1; + Assert.IsTrue(obj.TryGetValue("test", out int result)); + Assert.AreEqual(1, result); + Assert.IsFalse(obj.TryGetValue("nonExistantKey", out int result2)); + } + + + [TestMethod] + [Description("Tests MergeFromObject copies the data of other ParseObject")] + public void MergeFromObject_CopiesDataFromOtherObject() // Mock difficulty: 2 + { + var obj1 = new ParseObject("TestClass", Client.Services); + var obj2 = new ParseObject("TestClass", Client.Services); + obj2["test"] = "test"; + obj1.MergeFromObject(obj2); + + Assert.AreEqual("test", obj1["test"]); + } + [TestMethod] + [Description("Tests MutateState and checks if estimated data is updated after mutation")] + public void MutateState_UpdatesEstimatedData() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["test"] = 1; + obj.MutateState(m => m.ClassName = "NewTestClass"); + + Assert.IsTrue(obj.Keys.Contains("test")); + Assert.AreEqual("NewTestClass", obj.ClassName); + } + [TestMethod] + [Description("Tests that OnSettingValue Throws exceptions if key is null")] + public void OnSettingValue_ThrowsIfKeyIsNull() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + string key = null; + object value = "value"; + + Assert.ThrowsException(() => + { + obj.Set(key, value); + }); + } + [TestMethod] + [Description("Tests PerformOperation with ParseSetOperation correctly sets value")] + public void PerformOperation_SetsValueWithSetOperation() // Mock difficulty: 2 + { + var obj = new ParseObject("TestClass", Client.Services); + obj.PerformOperation("test", new ParseSetOperation("value")); + Assert.AreEqual("value", obj["test"]); + + } + [TestMethod] + [Description("Tests PerformOperation with ParseDeleteOperation deletes the value")] + public void PerformOperation_DeletesValueWithDeleteOperation() // Mock difficulty: 2 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["test"] = "test"; + obj.PerformOperation("test", ParseDeleteOperation.Instance); + + Assert.IsFalse(obj.ContainsKey("test")); + } + [TestMethod] + [Description("Tests the RebuildEstimatedData method rebuilds all data")] + public void RebuildEstimatedData_RebuildsData() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + obj["test"] = 1; + obj.MutateState(m => { }); // force a rebuild + Assert.IsTrue(obj.Keys.Contains("test")); + } + + [TestMethod] + [Description("Tests set method validates the key/value and throws an Argument Exception")] + public void Set_ThrowsArgumentExceptionForInvalidType() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + + Assert.ThrowsException(() => obj.Set("test", new object())); + } + [TestMethod] + [Description("Tests set method sets a new value")] + public void Set_SetsCorrectValue() // Mock difficulty: 1 + { + var obj = new ParseObject("TestClass", Client.Services); + + obj.Set("test", "test"); + Assert.AreEqual("test", obj["test"]); + } + + + #endregion + [TestMethod] + [Description("Tests that ParseObjectClass correctly extract properties and fields.")] + public void Constructor_ExtractsPropertiesCorrectly() // Mock difficulty: 1 + { + ConstructorInfo constructor = typeof(TestParseObject).GetConstructor(Type.EmptyTypes); + ParseObjectClass obj = new ParseObjectClass(typeof(TestParseObject), constructor); + Assert.AreEqual("TestParseObject", obj.DeclaredName); + Assert.IsTrue(obj.PropertyMappings.ContainsKey("Text2")); + Assert.AreEqual("text", obj.PropertyMappings["Text2"]); + } + + [TestMethod] + [Description("Tests that Instantiate can correctly instatiate with parameterless constructor.")] + public void Instantiate_WithParameterlessConstructor_CreatesInstance() // Mock difficulty: 1 + { + ConstructorInfo constructor = typeof(TestParseObject).GetConstructor(Type.EmptyTypes); + ParseObjectClass obj = new ParseObjectClass(typeof(TestParseObject), constructor); + ParseObject instance = obj.Instantiate(); + Assert.IsNotNull(instance); + Assert.IsInstanceOfType(instance, typeof(TestParseObject)); + } + [TestMethod] + [Description("Tests that Instantiate can correctly instantiate with IServiceHub constructor.")] + public void Instantiate_WithServiceHubConstructor_CreatesInstance() // Mock difficulty: 1 + { + ConstructorInfo constructor = typeof(ParseObject).GetConstructor(new[] { typeof(string), typeof(IServiceHub) }); + ParseObjectClass obj = new ParseObjectClass(typeof(ParseObject), constructor); + + ParseObject instance = obj.Instantiate(); + + Assert.IsNotNull(instance); + Assert.IsInstanceOfType(instance, typeof(ParseObject)); + } + + [TestMethod] + [Description("Tests that Instantiate Throws if contructor is invalid.")] + public void Instantiate_WithInvalidConstructor_ReturnsNull() + { + // Arrange + ConstructorInfo invalidConstructor = typeof(object).GetConstructor(Type.EmptyTypes); + var obj = new ParseObjectClass(typeof(object), invalidConstructor); + + // Act + var instance = obj.Instantiate(); + + // Assert + Assert.IsNull(instance); + } +} + + + +[ParseClassName(nameof(TestParseObject))] +public class TestParseObject : ParseObject +{ + public string Text { get; set; } + [ParseFieldName("text")] + public string Text2 { get; set; } + + public TestParseObject() { } + public TestParseObject(string className, IServiceHub serviceHub) : base(className, serviceHub) + { + } } +//so, I have mock difficulties, as it helps me understand the code better, bare with me! +//but I will try to understand it better and come back to it later - Surely when I Mock Parse Live Queries. \ No newline at end of file diff --git a/Parse.Tests/ProgressTests.cs b/Parse.Tests/ProgressTests.cs index 65c44784..8242b4f9 100644 --- a/Parse.Tests/ProgressTests.cs +++ b/Parse.Tests/ProgressTests.cs @@ -6,11 +6,30 @@ namespace Parse.Tests; -#warning Refactor if possible. [TestClass] public class ProgressTests { + private Mock> mockProgress; + private int _callbackCallCount; + + + [TestInitialize] + public void Initialize() + { + mockProgress = new Mock>(); + _callbackCallCount = 0; + mockProgress.Setup(obj => obj.Report(It.IsAny())) + .Callback(() => _callbackCallCount++); + + } + + [TestCleanup] + public void Cleanup() + { + mockProgress = null; // Ensure mock is released + } + [TestMethod] public void TestDownloadProgressEventGetterSetter() { @@ -34,9 +53,6 @@ public void TestUploadProgressEventGetterSetter() [TestMethod] public void TestObservingDownloadProgress() { - int called = 0; - Mock> mockProgress = new Mock>(); - mockProgress.Setup(obj => obj.Report(It.IsAny())).Callback(() => called++); IProgress progress = mockProgress.Object; progress.Report(new DataTransferLevel { Amount = 0.2f }); @@ -45,15 +61,12 @@ public void TestObservingDownloadProgress() progress.Report(new DataTransferLevel { Amount = 0.68f }); progress.Report(new DataTransferLevel { Amount = 0.88f }); - Assert.AreEqual(5, called); + Assert.AreEqual(5, _callbackCallCount); } [TestMethod] public void TestObservingUploadProgress() { - int called = 0; - Mock> mockProgress = new Mock>(); - mockProgress.Setup(obj => obj.Report(It.IsAny())).Callback(() => called++); IProgress progress = mockProgress.Object; progress.Report(new DataTransferLevel { Amount = 0.2f }); @@ -62,6 +75,6 @@ public void TestObservingUploadProgress() progress.Report(new DataTransferLevel { Amount = 0.68f }); progress.Report(new DataTransferLevel { Amount = 0.88f }); - Assert.AreEqual(5, called); + Assert.AreEqual(5, _callbackCallCount); } -} +} \ No newline at end of file diff --git a/Parse.Tests/UserTests.cs b/Parse.Tests/UserTests.cs index f1f7e6c8..21a8895b 100644 --- a/Parse.Tests/UserTests.cs +++ b/Parse.Tests/UserTests.cs @@ -32,17 +32,14 @@ public class UserTests [TestInitialize] public void SetUp() { - Client = new ParseClient(new ServerConnectionData { Test = true }); - Client.Publicize(); // Ensure the Clientinstance is globally available - + Client.Publicize(); // Ensure the Client instance is globally available Client.AddValidClass(); Client.AddValidClass(); // Ensure TLS 1.2 (or appropriate) is enabled if needed - System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; - + AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true); } [TestCleanup] public void CleanUp()