Skip to content
Merged
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
30 changes: 4 additions & 26 deletions src/Cronofy/CronofyAccountClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,7 @@ public void DeleteAllEvents()
var requestBody = new { delete_all = true };
request.SetJsonBody(requestBody);

var response = this.HttpClient.GetResponse(request);

if (response.Code != 202)
{
// TODO More useful exceptions for validation errors
throw new CronofyException("Request failed");
}
this.HttpClient.GetValidResponse(request);
}

/// <inheritdoc/>
Expand All @@ -334,13 +328,7 @@ public void DeleteAllEventsForCalendars(params string[] calendarIds)
var requestBody = new { calendar_ids = calendarIds };
request.SetJsonBody(requestBody);

var response = this.HttpClient.GetResponse(request);

if (response.Code != 202)
{
// TODO More useful exceptions for validation errors
throw new CronofyException("Request failed");
}
this.HttpClient.GetValidResponse(request);
}

/// <inheritdoc/>
Expand All @@ -358,12 +346,7 @@ public void DeleteExternalEvent(string calendarId, string eventUid)
var requestBody = new DeleteExternalEventRequest { EventUid = eventUid };
request.SetJsonBody(requestBody);

var response = this.HttpClient.GetResponse(request);

if (response.Code != 202)
{
throw new CronofyException("Request failed");
}
this.HttpClient.GetValidResponse(request);
}

/// <inheritdoc/>
Expand All @@ -381,12 +364,7 @@ public void ChangeParticipationStatus(string calendarId, string eventUid, Partic
var requestBody = new { status = status.ToString().ToLower() };
request.SetJsonBody(requestBody);

var response = this.HttpClient.GetResponse(request);

if (response.Code != 202)
{
throw new CronofyException("Request failed");
}
this.HttpClient.GetValidResponse(request);
}

/// <inheritdoc/>
Expand Down
7 changes: 1 addition & 6 deletions src/Cronofy/CronofyOAuthClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,7 @@ public void RevokeAuthorization(RevokeAuthorizationOptions options)

request.SetJsonBody(requestBody);

var response = this.HttpClient.GetResponse(request);

if (response.Code != 200)
{
throw new CronofyResponseException("Request failed", response);
}
this.HttpClient.GetValidResponse(request);
}

/// <inheritdoc/>
Expand Down
30 changes: 0 additions & 30 deletions src/Cronofy/ICronofyAccountClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,6 @@ public interface ICronofyAccountClient : ICronofyUserInfoClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
void UpsertEvent(string calendarId, IBuilder<UpsertEventRequest> eventBuilder);

/// <summary>
Expand All @@ -263,9 +260,6 @@ public interface ICronofyAccountClient : ICronofyUserInfoClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
void UpsertEvent(string calendarId, UpsertEventRequest eventRequest);

/// <summary>
Expand All @@ -285,9 +279,6 @@ public interface ICronofyAccountClient : ICronofyUserInfoClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
void DeleteEvent(string calendarId, string eventId);

/// <summary>
Expand All @@ -296,9 +287,6 @@ public interface ICronofyAccountClient : ICronofyUserInfoClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
void DeleteAllEvents();

/// <summary>
Expand All @@ -313,9 +301,6 @@ public interface ICronofyAccountClient : ICronofyUserInfoClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
void DeleteAllEventsForCalendars(params string[] calendarIds);

/// <summary>
Expand All @@ -335,9 +320,6 @@ public interface ICronofyAccountClient : ICronofyUserInfoClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
void DeleteExternalEvent(string calendarId, string eventUid);

/// <summary>
Expand All @@ -360,9 +342,6 @@ public interface ICronofyAccountClient : ICronofyUserInfoClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
void ChangeParticipationStatus(string calendarId, string eventUid, ParticipationStatus status);

/// <summary>
Expand All @@ -380,9 +359,6 @@ public interface ICronofyAccountClient : ICronofyUserInfoClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
Channel CreateChannel(string callbackUrl);

/// <summary>
Expand All @@ -401,9 +377,6 @@ public interface ICronofyAccountClient : ICronofyUserInfoClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
Channel CreateChannel(IBuilder<CreateChannelRequest> channelBuilder);

/// <summary>
Expand All @@ -421,9 +394,6 @@ public interface ICronofyAccountClient : ICronofyUserInfoClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
Channel CreateChannel(CreateChannelRequest channelRequest);

/// <summary>
Expand Down
9 changes: 0 additions & 9 deletions src/Cronofy/ICronofyOAuthClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ public interface ICronofyOAuthClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
OAuthToken GetTokenFromCode(string code, string redirectUri);

/// <summary>
Expand All @@ -53,9 +50,6 @@ public interface ICronofyOAuthClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
OAuthToken GetTokenFromRefreshToken(string refreshToken);

/// <summary>
Expand All @@ -74,9 +68,6 @@ public interface ICronofyOAuthClient
/// <exception cref="CronofyException">
/// Thrown if an error is encountered whilst making the request.
/// </exception>
/// <remarks>
/// TODO Validation exceptions.
/// </remarks>
OAuthToken ApplicationCalendar(string applicationCalendarId);

/// <summary>
Expand Down
49 changes: 49 additions & 0 deletions test/Cronofy.Test/CronofyAccountClientTests/BulkDelete.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,54 @@ public void CanDeleteAllForCalendars()

this.Client.DeleteAllEventsForCalendars(calendar1, calendar2);
}

[Test]
public void DeleteAllThrowsCronofyResponseExceptionOnFailure()
{
// Realistically this method should not result in validation errors as there are no user-provided inputs.
// But we can simulate error case handling here anyway to ensure this method is handling validation failures.
this.Http.Stub(
HttpDelete
.Url("https://api.cronofy.com/v1/events")
.RequestHeader("Authorization", "Bearer " + AccessToken)
.RequestHeader("Content-Type", "application/json; charset=utf-8")
.RequestBody("{\"delete_all\":true}")
.ResponseCode(422)
.ResponseBody(
"{\"errors:\":{\"delete_all\":[{\"key\":\"errors.must_be_boolean\",\"description\":\"must be a boolean value, either true or false\"}}"));

var exception = Assert.Throws<CronofyResponseException>(() => this.Client.DeleteAllEvents());

Assert.AreEqual(exception.Message, "Validation failed");
Assert.AreEqual(exception.Response.Code, 422);
Assert.AreEqual(
exception.Response.Body,
"{\"errors:\":{\"delete_all\":[{\"key\":\"errors.must_be_boolean\",\"description\":\"must be a boolean value, either true or false\"}}");
}

[Test]
public void DeleteAllForCalendarsThrowsCronofyResponseExceptionOnFailure()
{
const string calendar1 = "cal_1234_5678";
const string calendar2 = "cal_8765_4321";

this.Http.Stub(
HttpDelete
.Url("https://api.cronofy.com/v1/events")
.RequestHeader("Authorization", "Bearer " + AccessToken)
.RequestHeader("Content-Type", "application/json; charset=utf-8")
.RequestBodyFormat("{{\"calendar_ids\":[\"{0}\",\"{1}\"]}}", calendar1, calendar2)
.ResponseCode(422)
.ResponseBody(
"{\"errors:\":{\"calendar_ids\":[{\"key\":\"errors.invalid_calendar_ids\",\"description\":\"One or more of the calendar IDs provided was invalid\"}}"));

var exception = Assert.Throws<CronofyResponseException>(() => this.Client.DeleteAllEventsForCalendars(calendar1, calendar2));

Assert.AreEqual(exception.Message, "Validation failed");
Assert.AreEqual(exception.Response.Code, 422);
Assert.AreEqual(
exception.Response.Body,
"{\"errors:\":{\"calendar_ids\":[{\"key\":\"errors.invalid_calendar_ids\",\"description\":\"One or more of the calendar IDs provided was invalid\"}}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ internal sealed class ChangeParticipationStatus : Base
[TestCase(ParticipationStatus.Accepted, "accepted")]
[TestCase(ParticipationStatus.Tentative, "tentative")]
[TestCase(ParticipationStatus.Declined, "declined")]
public void CanDeleteEvent(ParticipationStatus status, string expectedStatus)
public void CanChangeParticipationStatus(ParticipationStatus status, string expectedStatus)
{
this.Http.Stub(
HttpPost
Expand All @@ -23,5 +23,22 @@ public void CanDeleteEvent(ParticipationStatus status, string expectedStatus)

this.Client.ChangeParticipationStatus(CalendarId, EventId, status);
}

[Test]
public void ChangeParticipationStatusThrowsCronofyResponseExceptionOnFailure()
{
this.Http.Stub(
HttpPost
.Url("https://api.cronofy.com/v1/calendars/" + CalendarId + "/events/" + EventId + "/participation_status")
.RequestHeader("Authorization", "Bearer " + AccessToken)
.RequestHeader("Content-Type", "application/json; charset=utf-8")
.RequestBody("{\"status\":\"declined\"}")
.ResponseCode(404));

var exception = Assert.Throws<CronofyResponseException>(() => this.Client.ChangeParticipationStatus(CalendarId, EventId, ParticipationStatus.Declined));

Assert.AreEqual(exception.Message, "Not found");
Assert.AreEqual(exception.Response.Code, 404);
}
}
}
44 changes: 44 additions & 0 deletions test/Cronofy.Test/CronofyAccountClientTests/DeleteEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,49 @@ public void CanDeleteExternalEvent()

this.Client.DeleteExternalEvent(CalendarId, eventUid);
}

[Test]
public void DeleteEventThrowsCronofyResponseExceptionOnFailure()
{
const string eventId = "qTtZdczOccgaPncGJaCiLg";

// Assume the calendar could not be found
this.Http.Stub(
HttpDelete
.Url("https://api.cronofy.com/v1/calendars/" + CalendarId + "/events")
.RequestHeader("Authorization", "Bearer " + AccessToken)
.RequestHeader("Content-Type", "application/json; charset=utf-8")
.RequestBodyFormat(@"{{""event_id"":""{0}""}}", eventId)
.ResponseCode(404));

var exception = Assert.Throws<CronofyResponseException>(() => this.Client.DeleteEvent(CalendarId, eventId));

Assert.AreEqual(exception.Message, "Not found");
Assert.AreEqual(exception.Response.Code, 404);
}

[Test]
public void DeleteExternalEventThrowsCronofyResponseExceptionOnFailure()
{
const string eventUid = "external_event_id";

this.Http.Stub(
HttpDelete
.Url("https://api.cronofy.com/v1/calendars/" + CalendarId + "/events")
.RequestHeader("Authorization", "Bearer " + AccessToken)
.RequestHeader("Content-Type", "application/json; charset=utf-8")
.RequestBodyFormat(@"{{""event_uid"":""{0}""}}", eventUid)
.ResponseCode(422)
.ResponseBody(
"{\"errors\":{\"event_uid\":[{\"key\":\"errors.must_be_external_event_uid\",\"description\":\"event uid must be a valid external event uid\"}]}"));

var exception = Assert.Throws<CronofyResponseException>(() => this.Client.DeleteExternalEvent(CalendarId, eventUid));

Assert.AreEqual(exception.Message, "Validation failed");
Assert.AreEqual(exception.Response.Code, 422);
Assert.AreEqual(
exception.Response.Body,
"{\"errors\":{\"event_uid\":[{\"key\":\"errors.must_be_external_event_uid\",\"description\":\"event uid must be a valid external event uid\"}]}");
}
}
}
27 changes: 27 additions & 0 deletions test/Cronofy.Test/CronofyOAuthClientTests/RevokeToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,32 @@ public void CanRevokeWithRemovePiiRequest()
RequestPiiErasure = true,
});
}

[Test]
public void RevokeAuthorizationThrowsCronofyResponseExceptionOnFailure()
{
const string sub = "acc_1234567890";

this.http.Stub(
HttpPost
.Url("https://app.cronofy.com/oauth/token/revoke")
.RequestHeader("Content-Type", "application/json; charset=utf-8")
.RequestBodyFormat(
"{{\"client_id\":\"{0}\",\"client_secret\":\"{1}\",\"sub\":\"{2}\",\"request_pii_erasure\":{3}}}",
ClientId, ClientSecret, sub, "true") // Need to provide bool as string to avoid incorrect serialization
.ResponseCode(400)
.ResponseBody("{\"error\":\"invalid_client\"}"));

var exception = Assert.Throws<CronofyResponseException>(() =>
this.client.RevokeAuthorization(new RevokeAuthorizationOptions
{
Sub = sub,
RequestPiiErasure = true,
}));

Assert.AreEqual(exception.Message, "Request failed - code=400");
Assert.AreEqual(exception.Response.Code, 400);
Assert.AreEqual(exception.Response.Body, "{\"error\":\"invalid_client\"}");
}
}
}
Loading