Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use DateTimeOffset Instead of Int64/long for Dates #119

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using System;
using System.IO;

using Intercom.Test;
using Newtonsoft.Json;
using NUnit.Framework;

using Intercom.Converters.ClassConverters;

namespace Intercom.Tests.Converters.ClassConverters
{
[TestFixture]
public class DateTimeOffsetJsonConverterTest : TestBase
{
private const string _DateCreatedISO = "1989-04-16T00:15:00Z";
private const string _DateCreatedUnix = "608688900";
private const string _Null = "null";

private readonly DateTimeOffsetJsonConverter _converter;

public DateTimeOffsetJsonConverterTest()
{
_converter = new DateTimeOffsetJsonConverter();
}

[TestCase(_DateCreatedUnix)]
public void ReadJson_ForDateTimeOffset_ReturnsValidDateTimeOffset(string json)
{
using (StringReader stringReader = new StringReader(json))
using (JsonReader jsonReader = new JsonTextReader(stringReader))
{
DateTimeOffset dateCreated = (DateTimeOffset)_converter.ReadJson(jsonReader, typeof(DateTimeOffset), null, null);

Assert.AreEqual(_ParseUtcDateString(_DateCreatedISO), dateCreated);
}
}

[TestCase(_DateCreatedISO)]
public void WriteJsonForDateTimeOffset_ForcesUtc(string input)
{
DateTimeOffset inputDate;

try
{
inputDate = _ParseUtcDateString(input);
}

catch (Exception ex)
{
throw new Exception("Failed to properly parse the test input.", ex);
}

inputDate.ToOffset(TimeSpan.FromHours(-5));

using (StringWriter stringWriter = new StringWriter())
using (JsonWriter jsonWriter = new JsonTextWriter(stringWriter))
{
_converter.WriteJson(jsonWriter, inputDate, null);

Assert.AreEqual(_DateCreatedUnix, stringWriter.GetStringBuilder().ToString());
}
}

[TestCase(_Null)]
public void ReadJson_ForNullableDateTimeOffset_ReturnsNull(string json)
{
using (StringReader stringReader = new StringReader(json))
using (JsonReader jsonReader = new JsonTextReader(stringReader))
{
DateTimeOffset? dateCreated = (DateTimeOffset?)_converter.ReadJson(jsonReader, typeof(DateTimeOffset?), null, null);

Assert.AreEqual(null, dateCreated);
}
}

[TestCase(null)]
public void WriteJsonForNullableDateTimeOffset_ReturnsNull(DateTimeOffset? input)
{
using (StringWriter stringWriter = new StringWriter())
using (JsonWriter jsonWriter = new JsonTextWriter(stringWriter))
{
_converter.WriteJson(jsonWriter, input, null);

Assert.AreEqual(_Null, stringWriter.GetStringBuilder().ToString());
}
}

[TestCase(_DateCreatedISO)]
public void WriteJson_ForDateTimeOffset_ReturnsValidUnixTimestamp(string input)
{
DateTimeOffset inputDate;

try
{
inputDate = _ParseUtcDateString(input);
}

catch (Exception ex)
{
throw new Exception("Failed to properly parse the test input.", ex);
}

using (StringWriter stringWriter = new StringWriter())
using (JsonWriter jsonWriter = new JsonTextWriter(stringWriter))
{
_converter.WriteJson(jsonWriter, inputDate, null);

Assert.AreEqual(_DateCreatedUnix, stringWriter.GetStringBuilder().ToString());
}
}

private DateTimeOffset _ParseUtcDateString(string input)
{
return DateTimeOffset.Parse(input);
}
}
}
14 changes: 2 additions & 12 deletions src/Intercom/Clients/UsersClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,36 +240,26 @@ public User Delete(String id)
return result.Result;
}

public User UpdateLastSeenAt(String id, long timestamp)
public User UpdateLastSeenAt(String id, DateTimeOffset timestamp)
{
if (String.IsNullOrEmpty(id))
{
throw new ArgumentNullException(nameof(id));
}

if (timestamp <= 0)
{
throw new ArgumentException("'timestamp' argument should be bigger than zero.");
}

ClientResponse<User> result = null;
String body = JsonConvert.SerializeObject(new { id = id, last_request_at = timestamp });
result = Post<User>(body);
return result.Result;
}

public User UpdateLastSeenAt(User user, long timestamp)
public User UpdateLastSeenAt(User user, DateTimeOffset timestamp)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}

if (timestamp <= 0)
{
throw new ArgumentException("'timestamp' argument should be bigger than zero.");
}

String body = String.Empty;

if (!String.IsNullOrEmpty(user.id))
Expand Down
65 changes: 65 additions & 0 deletions src/Intercom/Converters/ClassConverters/DateTimeJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;

using Newtonsoft.Json;

namespace Intercom.Converters.ClassConverters
{
public class DateTimeOffsetJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType.Equals(typeof(DateTimeOffset)) || objectType.Equals(typeof(DateTimeOffset?)));
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
object value = reader.Value;

if (value == null)
{
return null;
}

long unixTimestamp;

try
{
unixTimestamp = Convert.ToInt64(value);
}

catch (InvalidCastException ex)
{
throw new FormatException("Dates must be represented as UNIX timestamps in JSON.", ex);
}

DateTimeOffset unixEpoch = _GetUnixEpoch();
DateTimeOffset result = unixEpoch.AddSeconds(unixTimestamp);

return result;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteRawValue("null");

return;
}

DateTimeOffset unixEpoch = _GetUnixEpoch();
DateTimeOffset dateTimeOffset = (DateTimeOffset)value;

dateTimeOffset = dateTimeOffset.ToOffset(TimeSpan.Zero);

long unixTimestamp = Convert.ToInt64((dateTimeOffset - unixEpoch).TotalSeconds);

writer.WriteRawValue(unixTimestamp.ToString());
}

private DateTimeOffset _GetUnixEpoch()
{
return new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
}
}
}
13 changes: 9 additions & 4 deletions src/Intercom/Data/Company.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Intercom.Converters.AttributeConverters;
using Intercom.Converters.ClassConverters;

namespace Intercom.Data
{
Expand All @@ -12,10 +13,14 @@ public class Company : Model
public string name { get; set; }
public Plan plan { get; set; }
public string company_id { get; set; }
public long? remote_created_at { get; set; }
public long? created_at { get; set; }
public long? updated_at { get; set; }
public long? last_request_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? remote_created_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? created_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? updated_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? last_request_at { get; set; }
public int? monthly_spend { get; set; }
public int? session_count { get; set; }
public int? user_count { get; set; }
Expand Down
13 changes: 9 additions & 4 deletions src/Intercom/Data/Conversation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using Intercom.Clients;
using Intercom.Converters.AttributeConverters;
using Intercom.Converters.ClassConverters;
using Intercom.Core;
using Intercom.Data;
using Intercom.Exceptions;
Expand All @@ -11,10 +12,14 @@ namespace Intercom.Data
{
public class Conversation : Model
{
public long created_at { get; set; }
public long updated_at { get; set; }
public long? waiting_since { get; set; }
public long? snoozed_until { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset created_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset updated_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? waiting_since { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? snoozed_until { get; set; }
public Assignee assignee { get; set; }
public User user { get; set; }
public bool open { get; set; }
Expand Down
11 changes: 8 additions & 3 deletions src/Intercom/Data/ConversationPart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,21 @@
using Intercom.Clients;
using Intercom.Exceptions;
using System.Collections.Generic;
using Newtonsoft.Json;
using Intercom.Converters.ClassConverters;

namespace Intercom.Data
{
public class ConversationPart : Model
{
public string part_type { get; set; }
public string body { get; set; }
public long created_at { get; set; }
public long updated_at { get; set; }
public long notified_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset created_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset updated_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset notified_at { get; set; }
public Assignee assigned_to { get; set; }
public Author author { get; set; }
public List<Attachment> attachments { get; set; }
Expand Down
4 changes: 3 additions & 1 deletion src/Intercom/Data/Event.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Intercom.Converters.AttributeConverters;
using Intercom.Converters.ClassConverters;

namespace Intercom.Data
{
public class Event : Model
{
public string event_name { get; set; }
public long? created_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? created_at { get; set; }
public string user_id { get; set; }
public string email { get; set; }

Expand Down
5 changes: 4 additions & 1 deletion src/Intercom/Data/Note.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
using Intercom.Data;
using Intercom.Clients;
using Intercom.Exceptions;
using Newtonsoft.Json;
using Intercom.Converters.ClassConverters;

namespace Intercom.Data
{
public class Note : Model
{
public long? created_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? created_at { get; set; }
public string body { get; set; }
public Admin author { get; set; }
public User user { get; set; }
Expand Down
9 changes: 6 additions & 3 deletions src/Intercom/Data/Segment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@
using Intercom.Clients;

using Intercom.Exceptions;

using Newtonsoft.Json;
using Intercom.Converters.ClassConverters;

namespace Intercom.Data
{
public class Segment : Model
{
public string name { get; set; }
public long created_at { get; set; }
public long updated_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset created_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset updated_at { get; set; }

public Segment ()
{
Expand Down
13 changes: 9 additions & 4 deletions src/Intercom/Data/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Intercom.Converters.AttributeConverters;
using Intercom.Converters.ClassConverters;

namespace Intercom.Data
{
Expand All @@ -12,12 +13,16 @@ public class User : Model
public string email { get; set; }
public string phone { get; set; }
public string name { get; set; }
public long? updated_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? updated_at { get; set; }
public string last_seen_ip { get; set; }
public bool? unsubscribed_from_emails { get; set; }
public long? last_request_at { get; set; }
public long? signed_up_at { get; set; }
public long? created_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? last_request_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? signed_up_at { get; set; }
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset? created_at { get; set; }
public int? session_count { get; set; }
public bool? new_session { get; set; }
public string user_agent_data { get; set; }
Expand Down