public void Throws_On_OAuth_Code_Used() { string rawBody = "{\"error\":\"invalid_request\",\"error_description\":\"The authorization code was not found or was already used\"}"; var response = new HttpResponseMessage() { StatusCode = HttpStatusCode.NotAcceptable, ReasonPhrase = "Not Acceptable" }; ShopifyException ex = null; try { ShopifyService.CheckResponseExceptions(response, rawBody); } catch (ShopifyException e) { ex = e; } Assert.NotNull(ex); Assert.Contains("authorization code was not found or was already used", ex.Message); Assert.NotNull(ex.RawBody); Assert.Equal(1, ex.Errors.Count); Assert.Equal("invalid_request", ex.Errors.First().Key); Assert.Equal(1, ex.Errors.First().Value.Count()); }
/// <summary> /// Authorizes an application installation, generating an access token for the given shop. /// </summary> /// <param name="code">The authorization code generated by Shopify, which should be a parameter named 'code' on the request querystring.</param> /// <param name="myShopifyUrl">The store's *.myshopify.com URL, which should be a paramter named 'shop' on the request querystring.</param> /// <param name="shopifyApiKey">Your app's public API key.</param> /// <param name="shopifySecretKey">Your app's secret key.</param> /// <returns>The authorization result.</returns> public static async Task <AuthorizationResult> AuthorizeWithResult(string code, string myShopifyUrl, string shopifyApiKey, string shopifySecretKey) { var ub = new UriBuilder(ShopifyService.BuildShopUri(myShopifyUrl, false)) { Path = "admin/oauth/access_token" }; var content = new JsonContent(new { client_id = shopifyApiKey, client_secret = shopifySecretKey, code, }); using (var client = new HttpClient()) using (var msg = new CloneableRequestMessage(ub.Uri, HttpMethod.Post, content)) { var request = client.SendAsync(msg); var response = await request; var rawDataString = await response.Content.ReadAsStringAsync(); ShopifyService.CheckResponseExceptions(response, rawDataString); var json = JToken.Parse(rawDataString); return(new AuthorizationResult(json.Value <string>("access_token"), json.Value <string>("scope").Split(','))); } }
public static async Task <Order> GetShopifyOrder(IConfiguration appConfig, string orderName) { // get shopify configuration parameters string shopifyDomain = appConfig["ShopifyDomain"]; string shopifyAPIPassword = appConfig["ShopifyAPIPassword"]; string url = String.Format("https://{0}/admin/orders.json?name={1}&status=any", shopifyDomain, orderName); using (var client = new HttpClient()) { var msg = new HttpRequestMessage(method: HttpMethod.Get, requestUri: url); msg.Headers.Add("X-Shopify-Access-Token", shopifyAPIPassword); msg.Headers.Add("Accept", "application/json"); // request message is now ready to be sent via HttpClient HttpResponseMessage response = client.SendAsync(msg).Result; var rawResult = await response.Content.ReadAsStringAsync(); ShopifyService.CheckResponseExceptions(response, rawResult); var serializer = new JsonSerializer { DateParseHandling = DateParseHandling.DateTimeOffset }; var reader = new JsonTextReader(new StringReader(rawResult)); var data = serializer.Deserialize <JObject>(reader).SelectToken("orders"); var result = data.ToObject <List <Order> >(); return(result.FirstOrDefault()); } }
public void Throws_On_OAuth_Code_Used() { var rawBody = "{\"error\":\"invalid_request\",\"error_description\":\"The authorization code was not found or was already used\"}"; var res = new HttpResponseMessage() { StatusCode = HttpStatusCode.NotAcceptable, ReasonPhrase = "Not Acceptable", Content = new StringContent(rawBody) }; res.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); ShopifyException ex = null; try { ShopifyService.CheckResponseExceptions(res, rawBody); } catch (ShopifyException e) { ex = e; } Assert.NotNull(ex); Assert.NotNull(ex.RawBody); Assert.Single(ex.Errors); Assert.Equal("(406 Not Acceptable) invalid_request: The authorization code was not found or was already used", ex.Message); Assert.Equal("invalid_request: The authorization code was not found or was already used", ex.Errors.First()); }
public async Task Throws_On_Error_Object() { HttpResponseMessage response; string rawBody; ShopifyException ex = null; using (var client = new HttpClient()) { while (ex == null) { // This request will return a response which looks like { errors: { "order" : "some error message" } } using (var msg = PrepareRequest(HttpMethod.Post, "orders.json", new JsonContent(new { }))) { var req = client.SendAsync(msg); response = await req; rawBody = await response.Content.ReadAsStringAsync(); } try { ShopifyService.CheckResponseExceptions(response, rawBody); } catch (ShopifyRateLimitException) { // Ignore this exception and retry the request. // RateLimitExceptions may happen when all Exception tests are running and // execution policies are retrying. } catch (ShopifyException e) { ex = e; } } } Assert.NotNull(ex); Assert.NotEmpty(ex.Errors); Assert.Equal("(400 Bad Request) order: Required parameter missing or invalid", ex.Message); var error = ex.Errors.First(); Assert.Equal("order: Required parameter missing or invalid", error); }
public void Returns_Message_Saying_Json_Could_Not_Be_Parsed() { var json = "{}"; var res = BadResponse(HttpStatusCode.InternalServerError, json); ShopifyException ex = null; try { ShopifyService.CheckResponseExceptions(res, json); } catch (ShopifyException e) { ex = e; } Assert.NotNull(ex); Assert.Equal(HttpStatusCode.InternalServerError, ex.HttpStatusCode); Assert.Contains("(500 Internal Server Error) Shopify returned 500 Internal Server Error, but ShopifySharp was unable to parse the response JSON.", ex.Message); }
public void Exception_Contains_Message_From_Error_Type_One() { var json = "{\"errors\":\"foo error message\"}"; var code = HttpStatusCode.BadRequest; var res = BadResponse(code, json); ShopifyException ex = null; try { ShopifyService.CheckResponseExceptions(res, json); } catch (ShopifyException e) { ex = e; } Assert.NotNull(ex); Assert.Equal(code, ex.HttpStatusCode); Assert.Equal("(400 Bad Request) foo error message", ex.Message); }
public void Exception_Contains_Message_From_Error_Type_Five() { var json = "{\"error\":\"location_id must be specified when creating fulfillments.\"}"; var code = HttpStatusCode.BadRequest; var res = BadResponse(code, json); ShopifyException ex = null; try { ShopifyService.CheckResponseExceptions(res, json); } catch (ShopifyException e) { ex = e; } Assert.NotNull(ex); Assert.Equal(code, ex.HttpStatusCode); Assert.Equal("(400 Bad Request) location_id must be specified when creating fulfillments.", ex.Message); }
public async Task Throws_On_Error_String() { HttpResponseMessage response; string rawBody; ShopifyException ex = null; using (var client = new HttpClient()) { while (ex == null) { // This request will return a response which looks like { errors: "some error message"} using (var msg = PrepareRequest(HttpMethod.Get, "api_permissions/current.json")) { var req = client.SendAsync(msg); response = await req; rawBody = await response.Content.ReadAsStringAsync(); } try { ShopifyService.CheckResponseExceptions(response, rawBody); } catch (ShopifyRateLimitException) { // Ignore this exception and retry the request. // RateLimitExceptions may happen when all Exception tests are running and // execution policies are retrying. } catch (ShopifyException e) { ex = e; } } } Assert.NotNull(ex); Assert.Equal(1, ex.Errors.Count); Assert.Equal("Error", ex.Errors.First().Key); Assert.Equal(1, ex.Errors.First().Value.Count()); }
public void Returns_Message_Saying_There_Was_No_Json_To_Parse() { var json = "<p>testing</p>"; var res = BadResponse(HttpStatusCode.InternalServerError, json); res.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html"); ShopifyException ex = null; try { ShopifyService.CheckResponseExceptions(res, json); } catch (ShopifyException e) { ex = e; } Assert.NotNull(ex); Assert.Equal(HttpStatusCode.InternalServerError, ex.HttpStatusCode); Assert.Contains("(500 Internal Server Error) Shopify returned 500 Internal Server Error, but there was no JSON to parse into an error message.", ex.Message); }
public void Exception_Contains_Message_From_Error_Type_Three_With_Multiple_Messages() { var json = "{\"errors\":{\"order\":[\"foo error message\",\"bar error message\"]}}"; var code = HttpStatusCode.BadRequest; var res = BadResponse(code, json); ShopifyException ex = null; try { ShopifyService.CheckResponseExceptions(res, json); } catch (ShopifyException e) { ex = e; } Assert.NotNull(ex); Assert.Equal(code, ex.HttpStatusCode); Assert.Equal("(400 Bad Request) order: foo error message (and one other error)", ex.Message); Assert.Equal("order: bar error message", ex.Errors.Last()); }
public async Task Throws_On_Error_String() { HttpResponseMessage response; string rawBody; ShopifyException ex = null; using (var client = new HttpClient()) { while (ex == null) { // This request will return a response which looks like { errors: "some error message"} using (var msg = PrepareRequest(HttpMethod.Get, "api_permissions/current.json")) { var req = client.SendAsync(msg); response = await req; rawBody = await response.Content.ReadAsStringAsync(); } try { ShopifyService.CheckResponseExceptions(response, rawBody); } catch (ShopifyRateLimitException) { // Ignore this exception and retry the request. // RateLimitExceptions may happen when all Exception tests are running and // execution policies are retrying. } catch (ShopifyException e) { ex = e; } } } Assert.NotNull(ex); Assert.Single(ex.Errors); Assert.Equal("(403 Forbidden) Scope undefined for API access: api_permissions. Valid scopes: admin_login_tokens, admin_notifications, admin_shop_settings, all_orders, analytics, analytics_overviews, apps, assigned_fulfillment_orders, billing, capital, cash_tracking, channels, checkout_settings, checkouts, checkouts_vault_tokens, content, customer_payment_methods, customer_tags, customers, delivery, discounts, disputes, domains, draft_orders, fulfillments, gdpr_data_request, gift_card_adjustments, gift_cards, home, images, inventory, kit_skills, legal_policies, locales, locations, marketing_events, media_processing, merchant_managed_fulfillment_orders, meta_tags, mobile_payments, mobile_platform_applications, notifications, online_store, online_store_bot_protection, online_store_navigation, online_store_pages, online_store_preferences, order_edits, orders, payment_gateways, payment_sessions, payment_settings, physical_receipts, point_of_sale_devices, price_rules, product_engagements, product_inventory, product_listings, product_tags, products, publications, reports, resource_feedbacks, retail_addon_subscriptions, retail_bbpos_merchant, retail_roles, script_tags, scripts, shipping, shopify_payments, shopify_payments_accounts, shopify_payments_balance_debits, shopify_payments_bank_accounts, shopify_payments_bank_accounts_sensitive, shopify_payments_disputes, shopify_payments_legal_entities, shopify_payments_payouts, shopify_payments_payouts_status, smart_grid, social_network_accounts, taxes, themes, third_party_fulfillment_orders, tracking_pixels, translations, user_private_data, and users", ex.Message); Assert.Equal("Scope undefined for API access: api_permissions. Valid scopes: admin_login_tokens, admin_notifications, admin_shop_settings, all_orders, analytics, analytics_overviews, apps, assigned_fulfillment_orders, billing, capital, cash_tracking, channels, checkout_settings, checkouts, checkouts_vault_tokens, content, customer_payment_methods, customer_tags, customers, delivery, discounts, disputes, domains, draft_orders, fulfillments, gdpr_data_request, gift_card_adjustments, gift_cards, home, images, inventory, kit_skills, legal_policies, locales, locations, marketing_events, media_processing, merchant_managed_fulfillment_orders, meta_tags, mobile_payments, mobile_platform_applications, notifications, online_store, online_store_bot_protection, online_store_navigation, online_store_pages, online_store_preferences, order_edits, orders, payment_gateways, payment_sessions, payment_settings, physical_receipts, point_of_sale_devices, price_rules, product_engagements, product_inventory, product_listings, product_tags, products, publications, reports, resource_feedbacks, retail_addon_subscriptions, retail_bbpos_merchant, retail_roles, script_tags, scripts, shipping, shopify_payments, shopify_payments_accounts, shopify_payments_balance_debits, shopify_payments_bank_accounts, shopify_payments_bank_accounts_sensitive, shopify_payments_disputes, shopify_payments_legal_entities, shopify_payments_payouts, shopify_payments_payouts_status, smart_grid, social_network_accounts, taxes, themes, third_party_fulfillment_orders, tracking_pixels, translations, user_private_data, and users", ex.Errors.First()); }
public async Task Throws_On_Error_Object() { HttpResponseMessage response; string rawBody; ShopifyException ex = null; while (ex == null) { // This request will return a response which looks like { errors: { "order" : "some error message" } } using (var client = PrepareRequest("orders.json")) { var req = client.PostAsync(new JsonContent(new { }));; response = await req; rawBody = await req.ReceiveString(); } try { ShopifyService.CheckResponseExceptions(response, rawBody); } catch (ShopifyRateLimitException) { // Ignore this exception and retry the request. // RateLimitExceptions may happen when all Exception tests are running and // execution policies are retrying. } catch (ShopifyException e) { ex = e; } } Assert.NotNull(ex); Assert.True(ex.Errors.Count > 0); Assert.True(ex.Errors.Any(error => error.Key.Equals("order"))); Assert.NotNull(ex.Errors.First(err => err.Key.Equals("order")).Value.First()); Assert.True(ex.Errors.First(err => err.Key.Equals("order")).Value.Count() > 0); Assert.True(ex.Errors.All(err => err.Value.Count() > 0)); }
public void Returns_Message_About_The_StatusCode() { var req = new HttpResponseMessage(); req.StatusCode = System.Net.HttpStatusCode.InternalServerError; req.ReasonPhrase = "Internal Server Error"; ShopifyException ex = null; try { ShopifyService.CheckResponseExceptions(req, null); } catch (ShopifyException e) { ex = e; } Assert.NotNull(ex); Assert.Equal(ex.HttpStatusCode, System.Net.HttpStatusCode.InternalServerError); Assert.Contains("Response did not indicate success. Status: 500", ex.Message); }
public async Task Throws_On_Error_Arrays() { //Creating an order with tax lines on both line items and the order will return an error var order = new Order() { CreatedAt = DateTime.UtcNow, LineItems = new List <LineItem>() { new LineItem() { Title = "Click Keyboard", Price = 99.99m, Grams = 600, Quantity = 1, TaxLines = new List <TaxLine>() { new TaxLine() { Price = 1.0m, Rate = 0.01m, Title = "Keyboard tax" } } } }, TaxLines = new List <TaxLine>() { new TaxLine() { Price = 6.0m, Rate = 0.06m, Title = "State tax" } } }; HttpResponseMessage response; string rawBody; ShopifyException ex = null; using (var client = new HttpClient()) { while (ex == null) { // This request will return a response which looks like { errors: { "order" : [ "some error message" ] } } using (var msg = PrepareRequest(HttpMethod.Post, "orders.json", new JsonContent(new { order }))) { var req = client.SendAsync(msg); response = await req; rawBody = await response.Content.ReadAsStringAsync(); } try { ShopifyService.CheckResponseExceptions(response, rawBody); } catch (ShopifyRateLimitException) { // Ignore this exception and retry the request. // RateLimitExceptions may happen when all Exception tests are running and // execution policies are retrying. } catch (ShopifyException e) { ex = e; } } } Assert.NotNull(ex); Assert.NotEmpty(ex.Errors); Assert.NotNull(ex.RequestId); Assert.Equal("(422 Unprocessable Entity) order: Tax lines must be associated with either order or line item but not both", ex.Message); var error = ex.Errors.First(); Assert.Equal("order: Tax lines must be associated with either order or line item but not both", error); }
public async Task Throws_On_Error_Arrays() { //Creating an order with tax lines on both line items and the order will return an error var order = new Order() { CreatedAt = DateTime.UtcNow, LineItems = new List <LineItem>() { new LineItem() { Title = "Click Keyboard", Price = 99.99m, Grams = 600, Quantity = 1, TaxLines = new List <TaxLine>() { new TaxLine() { Price = 1.0m, Rate = 0.01m, Title = "Keyboard tax" } } } }, TaxLines = new List <TaxLine>() { new TaxLine() { Price = 6.0m, Rate = 0.06m, Title = "State tax" } } }; HttpResponseMessage response; string rawBody; ShopifyException ex = null; while (ex == null) { // This request will return a response which looks like { errors: { "order" : [ "some error message" ] } } using (var client = PrepareRequest("orders.json")) { var req = client.PostAsync(new JsonContent(new { order = order }));; response = await req; rawBody = await req.ReceiveString(); } try { ShopifyService.CheckResponseExceptions(response, rawBody); } catch (ShopifyRateLimitException) { // Ignore this exception and retry the request. // RateLimitExceptions may happen when all Exception tests are running and // execution policies are retrying. } catch (ShopifyException e) { ex = e; } } Assert.NotNull(ex); Assert.True(ex.Errors.Count > 0); Assert.NotNull(ex.RequestId); Assert.True(ex.Errors.Any(error => error.Key.Equals("order"))); Assert.NotNull(ex.Errors.First(err => err.Key.Equals("order")).Value.First()); Assert.True(ex.Errors.First(err => err.Key.Equals("order")).Value.Count() > 0); Assert.True(ex.Errors.All(err => err.Value.Count() > 0)); }