Skip to content

Commit a13c7ab

Browse files
committed
Moved responsibilities from ParseLiveQueryController to 2 new classes
1 parent 854beaa commit a13c7ab

17 files changed

+652
-111
lines changed

Parse.Tests/LiveQueryDualEventArgsTests.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,13 @@ namespace Parse.Tests;
1111
[TestClass]
1212
public class LiveQueryDualEventArgsTests
1313
{
14-
private ParseClient Client { get; set; }
14+
private ParseClient Client { get; } = new ParseClient(new ServerConnectionData { Test = true });
1515

16-
[TestInitialize]
17-
public void SetUp()
18-
{
19-
// Initialize the client and ensure the instance is set
20-
Client = new ParseClient(new ServerConnectionData { Test = true });
16+
public LiveQueryDualEventArgsTests()
17+
{
2118
Client.Publicize();
2219
}
2320

24-
[TestCleanup]
25-
public void TearDown() => (Client.Services as ServiceHub).Reset();
26-
2721
[TestMethod]
2822
public void TestConstructor()
2923
{
@@ -45,8 +39,8 @@ public void TestConstructor()
4539
objOrig.Set("test", "before");
4640
ParseLiveQueryDualEventArgs args = new ParseLiveQueryDualEventArgs(obj, objOrig);
4741

48-
Assert.AreEqual(obj, args.Object);
49-
Assert.AreEqual(objOrig, args.Original);
42+
Assert.AreSame(obj, args.Object);
43+
Assert.AreSame(objOrig, args.Original);
5044
}
5145

5246
[TestMethod]

Parse.Tests/LiveQueryEventArgsTests.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,13 @@ namespace Parse.Tests;
1111
[TestClass]
1212
public class LiveQueryEventArgsTests
1313
{
14-
private ParseClient Client { get; set; }
14+
private ParseClient Client { get; } = new ParseClient(new ServerConnectionData { Test = true });
1515

16-
[TestInitialize]
17-
public void SetUp()
16+
public LiveQueryEventArgsTests()
1817
{
19-
// Initialize the client and ensure the instance is set
20-
Client = new ParseClient(new ServerConnectionData { Test = true });
2118
Client.Publicize();
2219
}
2320

24-
[TestCleanup]
25-
public void TearDown() => (Client.Services as ServiceHub).Reset();
26-
2721
[TestMethod]
2822
public void TestConstructor()
2923
{
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using Microsoft.VisualStudio.TestTools.UnitTesting;
5+
using Parse.Abstractions.Platform.Objects;
6+
using Parse.Infrastructure;
7+
using Parse.Platform.LiveQueries;
8+
9+
namespace Parse.Tests;
10+
11+
[TestClass]
12+
public class LiveQueryMessageBuilderTests
13+
{
14+
private ParseClient Client { get; } = new ParseClient(
15+
new ServerConnectionData { Test = true },
16+
new LiveQueryServerConnectionData { ApplicationID = "TestApp", Key = "t3stK3y", Test = true });
17+
18+
public LiveQueryMessageBuilderTests()
19+
{
20+
Client.Publicize();
21+
}
22+
23+
[TestMethod]
24+
public void TestConstructor()
25+
{
26+
ParseLiveQueryMessageBuilder builder = new ParseLiveQueryMessageBuilder();
27+
28+
Assert.IsNotNull(builder, "Builder should not be null after construction.");
29+
}
30+
31+
[TestMethod]
32+
public async Task TestBuildConnectMessage()
33+
{
34+
ParseLiveQueryMessageBuilder builder = new ParseLiveQueryMessageBuilder();
35+
IDictionary<string, object> message = await builder.BuildConnectMessage();
36+
37+
Assert.IsNotNull(message);
38+
Assert.IsTrue(message.ContainsKey("op"));
39+
Assert.IsTrue(message.ContainsKey("applicationId"));
40+
Assert.IsTrue(message.ContainsKey("windowsKey"));
41+
Assert.HasCount(3, message);
42+
Assert.AreEqual("connect", message["op"]);
43+
Assert.AreEqual(Client.Services.LiveQueryServerConnectionData.ApplicationID, message["applicationId"]);
44+
Assert.AreEqual(Client.Services.LiveQueryServerConnectionData.Key, message["windowsKey"]);
45+
}
46+
47+
[TestMethod]
48+
public void TestBuildUnsubscribeMessage()
49+
{
50+
int requestId = 2;
51+
ParseLiveQueryMessageBuilder builder = new ParseLiveQueryMessageBuilder();
52+
IDictionary<string, object> message = builder.BuildUnsubscribeMessage(requestId);
53+
54+
Assert.IsNotNull(message);
55+
Assert.IsTrue(message.ContainsKey("op"));
56+
Assert.IsTrue(message.ContainsKey("requestId"));
57+
Assert.HasCount(2, message);
58+
Assert.AreEqual("unsubscribe", message["op"]);
59+
Assert.AreEqual(requestId, message["requestId"]);
60+
61+
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => builder.BuildUnsubscribeMessage(0));
62+
}
63+
64+
[TestMethod]
65+
public async Task TestBuildSubscribeMessage()
66+
{
67+
int requestId = 2;
68+
ParseLiveQuery<ParseObject> liveQuery = new ParseLiveQuery<ParseObject>(
69+
Client.Services,
70+
"DummyClass",
71+
new Dictionary<string, object> { { "foo", "bar" } },
72+
["foo"],
73+
["foo"]);
74+
ParseLiveQueryMessageBuilder builder = new ParseLiveQueryMessageBuilder();
75+
IDictionary<string, object> message = await builder.BuildSubscribeMessage<ParseObject>(requestId, liveQuery);
76+
77+
Assert.IsNotNull(message);
78+
Assert.HasCount(3, message);
79+
80+
Assert.IsTrue(message.ContainsKey("op"));
81+
Assert.AreEqual("subscribe", message["op"]);
82+
83+
Assert.IsTrue(message.ContainsKey("requestId"));
84+
Assert.AreEqual(requestId, message["requestId"]);
85+
86+
Assert.IsTrue(message.ContainsKey("query"));
87+
Assert.IsInstanceOfType<IDictionary<string, object>>(message["query"], "The 'query' value should be a Dictionary<string, object>.");
88+
Assert.HasCount(4, (IDictionary<string, object>) message["query"]);
89+
IDictionary<string, object> query = message["query"] as IDictionary<string, object>;
90+
91+
Assert.IsTrue(query.ContainsKey("className"), "The 'query' dictionary should contain the 'className' key.");
92+
Assert.AreEqual("DummyClass", query["className"], "The 'className' property should be 'DummyClass'.");
93+
94+
Assert.IsTrue(query.ContainsKey("where"), "The 'query' dictionary should contain the 'where' key.");
95+
Assert.IsInstanceOfType<IDictionary<string, object>>(query["where"], "The 'where' property should be a Dictionary<string, object>.");
96+
IDictionary<string, object> where = (IDictionary<string, object>) query["where"];
97+
Assert.HasCount(1, where, "The 'where' dictionary should contain exactly one key-value pair.");
98+
Assert.IsTrue(where.ContainsKey("foo"), "The 'where' dictionary should contain the 'foo' key.");
99+
Assert.AreEqual("bar", where["foo"], "The 'foo' property in 'where' should be 'bar'.");
100+
101+
Assert.IsTrue(query.ContainsKey("keys"), "The 'query' dictionary should contain the 'keys' key.");
102+
Assert.IsInstanceOfType<string[]>(query["keys"], "The 'keys' property should be a string array.");
103+
Assert.HasCount(1, (string[]) query["keys"], "The 'keys' array should contain exactly one element.");
104+
Assert.AreEqual("foo", ((string[]) query["keys"])[0], "The 'keys' parameter should contain 'foo'.");
105+
106+
Assert.IsTrue(query.ContainsKey("watch"), "The 'query' dictionary should contain the 'watch' key.");
107+
Assert.IsInstanceOfType<string[]>(query["watch"], "The 'watch' property should be a string array.");
108+
Assert.HasCount(1, (string[]) query["watch"], "The 'watch' array should contain exactly one element.");
109+
Assert.AreEqual("foo", ((string[]) query["watch"])[0], "The 'watch' parameter should contain 'foo'.");
110+
111+
await Assert.ThrowsExactlyAsync<ArgumentOutOfRangeException>(async () => await builder.BuildSubscribeMessage<ParseObject>(0, liveQuery));
112+
await Assert.ThrowsExactlyAsync<ArgumentNullException>(async () => await builder.BuildSubscribeMessage<ParseObject>(requestId, null));
113+
}
114+
115+
[TestMethod]
116+
public async Task TestBuildUpdateSubscriptionMessage()
117+
{
118+
int requestId = 2;
119+
ParseLiveQuery<ParseObject> liveQuery = new ParseLiveQuery<ParseObject>(
120+
Client.Services,
121+
"DummyClass",
122+
new Dictionary<string, object> { { "foo", "bar" } },
123+
["foo"],
124+
["foo"]);
125+
ParseLiveQueryMessageBuilder builder = new ParseLiveQueryMessageBuilder();
126+
IDictionary<string, object> message = await builder.BuildUpdateSubscriptionMessage<ParseObject>(requestId, liveQuery);
127+
128+
Assert.IsNotNull(message);
129+
Assert.HasCount(3, message);
130+
131+
Assert.IsTrue(message.ContainsKey("op"));
132+
Assert.AreEqual("update", message["op"]);
133+
134+
Assert.IsTrue(message.ContainsKey("requestId"));
135+
Assert.AreEqual(requestId, message["requestId"]);
136+
137+
Assert.IsTrue(message.ContainsKey("query"));
138+
Assert.IsInstanceOfType<IDictionary<string, object>>(message["query"], "The 'query' value should be a Dictionary<string, object>.");
139+
Assert.HasCount(4, (IDictionary<string, object>) message["query"]);
140+
IDictionary<string, object> query = message["query"] as IDictionary<string, object>;
141+
142+
Assert.IsTrue(query.ContainsKey("className"), "The 'query' dictionary should contain the 'className' key.");
143+
Assert.AreEqual("DummyClass", query["className"], "The 'className' property should be 'DummyClass'.");
144+
145+
Assert.IsTrue(query.ContainsKey("where"), "The 'query' dictionary should contain the 'where' key.");
146+
Assert.IsInstanceOfType<IDictionary<string, object>>(query["where"], "The 'where' property should be a Dictionary<string, object>.");
147+
IDictionary<string, object> where = (IDictionary<string, object>) query["where"];
148+
Assert.HasCount(1, where, "The 'where' dictionary should contain exactly one key-value pair.");
149+
Assert.IsTrue(where.ContainsKey("foo"), "The 'where' dictionary should contain the 'foo' key.");
150+
Assert.AreEqual("bar", where["foo"], "The 'foo' property in 'where' should be 'bar'.");
151+
152+
Assert.IsTrue(query.ContainsKey("keys"), "The 'query' dictionary should contain the 'keys' key.");
153+
Assert.IsInstanceOfType<string[]>(query["keys"], "The 'keys' property should be a string array.");
154+
Assert.HasCount(1, (string[]) query["keys"], "The 'keys' array should contain exactly one element.");
155+
Assert.AreEqual("foo", ((string[]) query["keys"])[0], "The 'keys' parameter should contain 'foo'.");
156+
157+
Assert.IsTrue(query.ContainsKey("watch"), "The 'query' dictionary should contain the 'watch' key.");
158+
Assert.IsInstanceOfType<string[]>(query["watch"], "The 'watch' property should be a string array.");
159+
Assert.HasCount(1, (string[]) query["watch"], "The 'watch' array should contain exactly one element.");
160+
Assert.AreEqual("foo", ((string[]) query["watch"])[0], "The 'watch' parameter should contain 'foo'.");
161+
162+
await Assert.ThrowsExactlyAsync<ArgumentOutOfRangeException>(async () => await builder.BuildUpdateSubscriptionMessage<ParseObject>(0, liveQuery));
163+
await Assert.ThrowsExactlyAsync<ArgumentNullException>(async () => await builder.BuildUpdateSubscriptionMessage<ParseObject>(requestId, null));
164+
}
165+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
using Parse.Abstractions.Platform.Objects;
5+
using Parse.Infrastructure;
6+
using Parse.Platform.LiveQueries;
7+
8+
namespace Parse.Tests;
9+
10+
[TestClass]
11+
public class LiveQueryMessageParserTests
12+
{
13+
private ParseClient Client { get; } = new ParseClient(new ServerConnectionData { Test = true });
14+
15+
public LiveQueryMessageParserTests()
16+
{
17+
Client.Publicize();
18+
}
19+
20+
[TestMethod]
21+
public void TestConstructor()
22+
{
23+
ParseLiveQueryMessageParser parser = new ParseLiveQueryMessageParser(Client.Services.Decoder);
24+
25+
Assert.IsNotNull(parser, "Parser should not be null after construction.");
26+
27+
Assert.ThrowsExactly<ArgumentNullException>(() => new ParseLiveQueryMessageParser(null));
28+
}
29+
30+
[TestMethod]
31+
public void TestGetClientId()
32+
{
33+
ParseLiveQueryMessageParser parser = new ParseLiveQueryMessageParser(Client.Services.Decoder);
34+
string clientId = "someClientId";
35+
36+
IDictionary<string, object> message = new Dictionary<string, object> { { "clientId", clientId } };
37+
Assert.AreEqual(clientId, parser.GetClientId(message));
38+
39+
Assert.ThrowsExactly<ArgumentNullException>(() => parser.GetClientId(null));
40+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetClientId(new Dictionary<string, object> { { "wrongKey", "someClientId" } }));
41+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetClientId(new Dictionary<string, object> { { "clientId", 12345 } }));
42+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetClientId(new Dictionary<string, object> { { "clientId", "" } }));
43+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetClientId(new Dictionary<string, object> { { "clientId", " " } }));
44+
}
45+
46+
[TestMethod]
47+
public void TestGetRequestId()
48+
{
49+
ParseLiveQueryMessageParser parser = new ParseLiveQueryMessageParser(Client.Services.Decoder);
50+
int requestId = 42;
51+
52+
IDictionary<string, object> message = new Dictionary<string, object> { { "requestId", (long) requestId } };
53+
Assert.AreEqual(requestId, parser.GetRequestId(message));
54+
55+
Assert.ThrowsExactly<ArgumentNullException>(() => parser.GetRequestId(null));
56+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetRequestId(new Dictionary<string, object> { { "wrongKey", 42L } }));
57+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetRequestId(new Dictionary<string, object> { { "requestId", -1L } }));
58+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetRequestId(new Dictionary<string, object> { { "requestId", 0L } }));
59+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetRequestId(new Dictionary<string, object> { { "requestId", "notAnInteger" } }));
60+
}
61+
62+
[TestMethod]
63+
public void TestGetObjectState()
64+
{
65+
ParseLiveQueryMessageParser parser = new ParseLiveQueryMessageParser(Client.Services.Decoder);
66+
IDictionary<string, object> objData = new Dictionary<string, object>
67+
{
68+
{ "objectId", "obj123" },
69+
{ "className", "TestClass" },
70+
{ "createdAt", "2023-10-01T12:00.000Z" },
71+
{ "updatedAt", "2023-10-01T12:00.000Z" },
72+
{
73+
"ACL", new Dictionary<string, object>
74+
{
75+
{ "*", new Dictionary<string, object>{ { "read", true } } }
76+
}
77+
},
78+
{ "foo", "bar" }
79+
};
80+
81+
IDictionary<string, object> message = new Dictionary<string, object> { { "object", objData } };
82+
IObjectState state = parser.GetObjectState(message);
83+
Assert.IsNotNull(state);
84+
Assert.AreEqual("obj123", state.ObjectId);
85+
Assert.AreEqual("bar", state["foo"]);
86+
87+
Assert.ThrowsExactly<ArgumentNullException>(() => parser.GetObjectState(null));
88+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetObjectState(new Dictionary<string, object> { { "wrongKey", objData } }));
89+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetObjectState(new Dictionary<string, object> { { "object", "notADictionary" } }));
90+
}
91+
92+
[TestMethod]
93+
public void TestGetOriginalState()
94+
{
95+
ParseLiveQueryMessageParser parser = new ParseLiveQueryMessageParser(Client.Services.Decoder);
96+
IDictionary<string, object> objData = new Dictionary<string, object>
97+
{
98+
{ "objectId", "obj123" },
99+
{ "className", "TestClass" },
100+
{ "createdAt", "2023-10-01T12:00.000Z" },
101+
{ "updatedAt", "2023-10-01T12:00.000Z" },
102+
{
103+
"ACL", new Dictionary<string, object>
104+
{
105+
{ "*", new Dictionary<string, object>{ { "read", true } } }
106+
}
107+
},
108+
{ "foo", "bar" }
109+
};
110+
IDictionary<string, object> message = new Dictionary<string, object> { { "original", objData } };
111+
112+
IObjectState state = parser.GetOriginalState(message);
113+
Assert.IsNotNull(state);
114+
Assert.AreEqual("obj123", state.ObjectId);
115+
Assert.AreEqual("bar", state["foo"]);
116+
117+
Assert.ThrowsExactly<ArgumentNullException>(() => parser.GetOriginalState(null));
118+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetOriginalState(new Dictionary<string, object> { { "wrongKey", objData } }));
119+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetOriginalState(new Dictionary<string, object> { { "original", "notADictionary" } }));
120+
}
121+
122+
[TestMethod]
123+
public void TestGetError()
124+
{
125+
ParseLiveQueryMessageParser parser = new ParseLiveQueryMessageParser(Client.Services.Decoder);
126+
int errorCode = 123;
127+
string errorMessage = "An error occurred";
128+
bool reconnect = true;
129+
IDictionary<string, object> message = new Dictionary<string, object>
130+
{
131+
{ "code", (long) errorCode },
132+
{ "error", errorMessage },
133+
{ "reconnect", reconnect }
134+
};
135+
136+
(int code, string error, bool shouldReconnect) = parser.GetError(message);
137+
Assert.AreEqual(errorCode, code);
138+
Assert.AreEqual(errorMessage, error);
139+
Assert.AreEqual(reconnect, shouldReconnect);
140+
141+
Assert.ThrowsExactly<ArgumentNullException>(() => parser.GetError(null));
142+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetError(new Dictionary<string, object> { { "wrongField", 123 } }));
143+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetError(new Dictionary<string, object> { { "code", "notALong" }, { "error", errorMessage }, { "reconnect", reconnect } }));
144+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetError(new Dictionary<string, object> { { "code", (long) errorCode }, { "error", 12345 }, { "reconnect", reconnect } }));
145+
Assert.ThrowsExactly<ArgumentException>(() => parser.GetError(new Dictionary<string, object> { { "code", (long) errorCode }, { "error", errorMessage }, { "reconnect", "notABoolean" } }));
146+
}
147+
}

0 commit comments

Comments
 (0)