From 8dacb6440e16953a561f64431dc4969759572d38 Mon Sep 17 00:00:00 2001 From: bodrovis Date: Tue, 14 May 2024 21:46:39 +0300 Subject: [PATCH] Version 3.1.0 --- .github/workflows/ci.yml | 2 +- docs/Gemfile | 6 +- docs/Gemfile.lock | 127 +++++++++--------- docs/additional_info/changelog.md | 11 ++ docs/api/getting-started.md | 11 ++ docs/api/keys.md | 2 + docs/api/translations.md | 2 + lib/elixir_lokalise_api.ex | 12 +- lib/elixir_lokalise_api/collections/keys.ex | 1 + .../collections/translations.ex | 3 +- lib/elixir_lokalise_api/config.ex | 2 +- lib/elixir_lokalise_api/processor.ex | 14 +- mix.exs | 8 +- mix.lock | 26 ++-- .../endpoints/keys_test.exs | 12 ++ .../endpoints/translations_test.exs | 16 +++ test/fixtures/cassettes/keys_find_cursor.json | 45 +++++++ .../translations_all_paginated_cursor.json | 45 +++++++ 18 files changed, 253 insertions(+), 92 deletions(-) create mode 100644 test/fixtures/cassettes/keys_find_cursor.json create mode 100644 test/fixtures/cassettes/translations_all_paginated_cursor.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 958d7ce..6b1c61e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: fail-fast: false matrix: include: - - elixir: 1.15.x + - elixir: 1.16.x otp: 26 env: MIX_ENV: test diff --git a/docs/Gemfile b/docs/Gemfile index 9079772..1902a3c 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -17,17 +17,17 @@ gem 'minima', '~> 2.0' # If you want to use GitHub Pages, remove the "gem "jekyll"" above and # uncomment the line below. To upgrade, run `bundle update github-pages`. -gem 'github-pages', '~> 228', group: :jekyll_plugins +gem 'github-pages', '~> 231', group: :jekyll_plugins # If you have any plugins, put them here! group :jekyll_plugins do - gem 'jekyll-feed', '~> 0.15' + gem 'jekyll-feed', '~> 0.17' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem # and associated library. install_if -> { RUBY_PLATFORM =~ /mingw|mswin|java/ } do - gem 'tzinfo', '~> 1.2' + gem 'tzinfo', '~> 2.0' gem 'tzinfo-data' end diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index 54c4900..86dcfdd 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,24 +1,31 @@ GEM remote: https://rubygems.org/ specs: - activesupport (6.0.6.1) + activesupport (7.1.3.2) + base64 + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - zeitwerk (~> 2.2, >= 2.2.2) - addressable (2.8.5) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + minitest (>= 5.1) + mutex_m + tzinfo (~> 2.0) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) base64 (0.2.0) + bigdecimal (3.1.8) coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.11.1) + coffee-script-source (1.12.2) colorator (1.1.0) commonmarker (0.23.10) - concurrent-ruby (1.2.2) - dnsruby (1.70.0) + concurrent-ruby (1.2.3) + connection_pool (2.4.1) + dnsruby (1.72.1) simpleidn (~> 0.2.1) + drb (2.2.1) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) @@ -26,24 +33,23 @@ GEM ffi (>= 1.15.0) eventmachine (1.2.7) execjs (2.9.1) - faraday (2.7.12) - base64 - faraday-net_http (>= 2.0, < 3.1) - ruby2_keywords (>= 0.0.4) - faraday-net_http (3.0.2) - ffi (1.16.3-x64-mingw-ucrt) + faraday (2.9.0) + faraday-net_http (>= 2.0, < 3.2) + faraday-net_http (3.1.0) + net-http + ffi (1.16.3) forwardable-extended (2.6.0) - gemoji (3.0.1) - github-pages (228) - github-pages-health-check (= 1.17.9) - jekyll (= 3.9.3) - jekyll-avatar (= 0.7.0) - jekyll-coffeescript (= 1.1.1) + gemoji (4.1.0) + github-pages (231) + github-pages-health-check (= 1.18.2) + jekyll (= 3.9.5) + jekyll-avatar (= 0.8.0) + jekyll-coffeescript (= 1.2.2) jekyll-commonmark-ghpages (= 0.4.0) - jekyll-default-layout (= 0.1.4) - jekyll-feed (= 0.15.1) + jekyll-default-layout (= 0.1.5) + jekyll-feed (= 0.17.0) jekyll-gist (= 1.5.0) - jekyll-github-metadata (= 2.13.0) + jekyll-github-metadata (= 2.16.1) jekyll-include-cache (= 0.2.1) jekyll-mentions (= 1.6.0) jekyll-optional-front-matter (= 0.3.2) @@ -70,28 +76,28 @@ GEM jekyll-theme-tactile (= 0.2.0) jekyll-theme-time-machine (= 0.2.0) jekyll-titles-from-headings (= 0.5.3) - jemoji (= 0.12.0) - kramdown (= 2.3.2) + jemoji (= 0.13.0) + kramdown (= 2.4.0) kramdown-parser-gfm (= 1.1.0) liquid (= 4.0.4) mercenary (~> 0.3) minima (= 2.5.1) nokogiri (>= 1.13.6, < 2.0) - rouge (= 3.26.0) + rouge (= 3.30.0) terminal-table (~> 1.4) - github-pages-health-check (1.17.9) + github-pages-health-check (1.18.2) addressable (~> 2.3) dnsruby (~> 1.60) - octokit (~> 4.0) - public_suffix (>= 3.0, < 5.0) + octokit (>= 4, < 8) + public_suffix (>= 3.0, < 6.0) typhoeus (~> 1.3) html-pipeline (2.14.3) activesupport (>= 2) nokogiri (>= 1.4) http_parser.rb (0.8.0) - i18n (1.14.1) + i18n (1.14.5) concurrent-ruby (~> 1.0) - jekyll (3.9.3) + jekyll (3.9.5) addressable (~> 2.4) colorator (~> 1.0) em-websocket (~> 0.5) @@ -104,11 +110,11 @@ GEM pathutil (~> 0.9) rouge (>= 1.7, < 4) safe_yaml (~> 1.0) - jekyll-avatar (0.7.0) + jekyll-avatar (0.8.0) jekyll (>= 3.0, < 5.0) - jekyll-coffeescript (1.1.1) + jekyll-coffeescript (1.2.2) coffee-script (~> 2.2) - coffee-script-source (~> 1.11.1) + coffee-script-source (~> 1.12) jekyll-commonmark (1.4.0) commonmarker (~> 0.22) jekyll-commonmark-ghpages (0.4.0) @@ -116,15 +122,15 @@ GEM jekyll (~> 3.9.0) jekyll-commonmark (~> 1.4.0) rouge (>= 2.0, < 5.0) - jekyll-default-layout (0.1.4) - jekyll (~> 3.0) - jekyll-feed (0.15.1) + jekyll-default-layout (0.1.5) + jekyll (>= 3.0, < 5.0) + jekyll-feed (0.17.0) jekyll (>= 3.7, < 5.0) jekyll-gist (1.5.0) octokit (~> 4.2) - jekyll-github-metadata (2.13.0) + jekyll-github-metadata (2.16.1) jekyll (>= 3.4, < 5.0) - octokit (~> 4.0, != 4.4.0) + octokit (>= 4, < 7, != 4.4.0) jekyll-include-cache (0.2.1) jekyll (>= 3.7, < 5.0) jekyll-mentions (1.6.0) @@ -195,16 +201,16 @@ GEM jekyll (>= 3.3, < 5.0) jekyll-watch (2.2.1) listen (~> 3.0) - jemoji (0.12.0) - gemoji (~> 3.0) + jemoji (0.13.0) + gemoji (>= 3, < 5) html-pipeline (~> 2.2) jekyll (>= 3.0, < 5.0) - kramdown (2.3.2) + kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) liquid (4.0.4) - listen (3.8.0) + listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) mercenary (0.3.6) @@ -212,22 +218,24 @@ GEM jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) - minitest (5.20.0) - nokogiri (1.15.5-x64-mingw-ucrt) + minitest (5.22.3) + mutex_m (0.2.0) + net-http (0.4.1) + uri + nokogiri (1.16.5-x64-mingw-ucrt) racc (~> 1.4) octokit (4.25.1) faraday (>= 1, < 3) sawyer (~> 0.9) pathutil (0.16.2) forwardable-extended (~> 2.6) - public_suffix (4.0.7) + public_suffix (5.0.5) racc (1.7.3) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) rexml (3.2.6) - rouge (3.26.0) - ruby2_keywords (0.0.5) + rouge (3.30.0) rubyzip (2.3.2) safe_yaml (1.0.5) sass (3.7.4) @@ -238,36 +246,35 @@ GEM sawyer (0.9.2) addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) - simpleidn (0.2.1) + simpleidn (0.2.2) unf (~> 0.1.4) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) - thread_safe (0.3.6) typhoeus (1.4.1) ethon (>= 0.9.0) - tzinfo (1.2.11) - thread_safe (~> 0.1) - tzinfo-data (1.2023.3) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + tzinfo-data (1.2024.1) tzinfo (>= 1.0.0) unf (0.1.4) unf_ext - unf_ext (0.0.9.1-x64-mingw-ucrt) + unf_ext (0.0.9.1) unicode-display_width (1.8.0) + uri (0.13.0) wdm (0.1.1) - zeitwerk (2.6.12) PLATFORMS x64-mingw-ucrt DEPENDENCIES - github-pages (~> 228) + github-pages (~> 231) jekyll (~> 3.9.0) - jekyll-feed (~> 0.15) + jekyll-feed (~> 0.17) kramdown-parser-gfm minima (~> 2.0) - tzinfo (~> 1.2) + tzinfo (~> 2.0) tzinfo-data wdm (~> 0.1.0) BUNDLED WITH - 2.4.22 + 2.5.10 diff --git a/docs/additional_info/changelog.md b/docs/additional_info/changelog.md index 4b940e0..62853c6 100644 --- a/docs/additional_info/changelog.md +++ b/docs/additional_info/changelog.md @@ -1,5 +1,16 @@ # Changelog +## 3.1.0 (14-May-2024) + +* Add support for [cursor pagination](https://lokalise.github.io/elixir-lokalise-api/api/getting-started#cursor-pagination) for List keys and List translation endpoints: + +```elixir +{:ok, %KeysCollection{} = keys} = Keys.all(@project_id, limit: 2, pagination: "cursor", cursor: "eyIxIjozNzk3ODEzODh9") + +keys.per_page_limit # => 2 +keys.next_cursor # => "eyIxIjo0NTc4NDUxMDd9" +``` + ## 3.0.0 (02-Feb-2023) * Elixir v1.14+ is required. diff --git a/docs/api/getting-started.md b/docs/api/getting-started.md index c5d5db3..03ceaa1 100644 --- a/docs/api/getting-started.md +++ b/docs/api/getting-started.md @@ -116,6 +116,17 @@ projects |> Pagination.next_page() # => What is the number of the next page? projects |> Pagination.prev_page() # => What is the number of the previous page? ``` +### Cursor pagination + +The [List Keys](https://developers.lokalise.com/reference/list-all-keys) and [List Translations](https://developers.lokalise.com/reference/list-all-translations) endpoints support cursor pagination, which is recommended for its faster performance compared to traditional "offset" pagination. By default, "offset" pagination is used, so you must explicitly set `pagination` to `"cursor"` to use cursor pagination: + +```elixir +{:ok, %KeysCollection{} = keys} = Keys.all(@project_id, limit: 2, pagination: "cursor", cursor: "eyIxIjozNzk3ODEzODh9") + +keys.per_page_limit # => 2 +keys.next_cursor # => "eyIxIjo0NTc4NDUxMDd9" +``` + ## Branching If you are using [project branching feature](https://docs.lokalise.com/en/articles/3391861-project-branching), simply add branch name separated by semicolon to your project ID in any endpoint to access the branch. For example, in order to access `new-feature` branch for the project with an id `123abcdef.01`: diff --git a/docs/api/keys.md b/docs/api/keys.md index d430324..486d5b1 100644 --- a/docs/api/keys.md +++ b/docs/api/keys.md @@ -4,6 +4,8 @@ [Doc](https://developers.lokalise.com/reference/list-all-keys) +**This endpoint also supports cursor pagination which is now a recommended approach, especially for fetching large amounts of data. Please [learn more in the Pagination docs](https://lokalise.github.io/elixir-lokalise-api/api/getting-started#cursor-pagination).** + ```elixir {:ok, keys} = ElixirLokaliseApi.Keys.all(project_id, page: 2, limit: 3) diff --git a/docs/api/translations.md b/docs/api/translations.md index a0ca6d9..abe26f5 100644 --- a/docs/api/translations.md +++ b/docs/api/translations.md @@ -4,6 +4,8 @@ [Doc](https://developers.lokalise.com/reference/list-all-translations) +**This endpoint also supports cursor pagination which is now a recommended approach, especially for fetching large amounts of data. Please [learn more in the Pagination docs](https://lokalise.github.io/elixir-lokalise-api/api/getting-started#cursor-pagination).** + ```elixir {:ok, translations} = ElixirLokaliseApi.Translations.all(@project_id, filter_is_reviewed: 0, page: 2, limit: 1) diff --git a/lib/elixir_lokalise_api.ex b/lib/elixir_lokalise_api.ex index b512208..0a68f7d 100644 --- a/lib/elixir_lokalise_api.ex +++ b/lib/elixir_lokalise_api.ex @@ -1,19 +1,19 @@ defmodule ElixirLokaliseApi do @moduledoc """ `ElixirLokaliseApi` is an official client (interface) for the Lokalise APIv2. - + Learn more about Lokalise API at [https://developers.lokalise.com/reference/lokalise-rest-api](https://developers.lokalise.com/reference/lokalise-rest-api). - + To get started, you will need an API token that can be generated in your Lokalise profile. - + This token should be stored in your config file, for example `dev.exs`: - + config :elixir_lokalise_api, api_token: {:system, "LOKALISE_API_TOKEN"} - + Next, use one of the endpoints to send requests, for example: - + {:ok, project} = ElixirLokaliseApi.Projects.find("123.abc") """ end diff --git a/lib/elixir_lokalise_api/collections/keys.ex b/lib/elixir_lokalise_api/collections/keys.ex index 35bc5cc..0fd4933 100644 --- a/lib/elixir_lokalise_api/collections/keys.ex +++ b/lib/elixir_lokalise_api/collections/keys.ex @@ -6,5 +6,6 @@ defmodule ElixirLokaliseApi.Collection.Keys do page_count: nil, per_page_limit: nil, current_page: nil, + next_cursor: nil, errors: [] end diff --git a/lib/elixir_lokalise_api/collections/translations.ex b/lib/elixir_lokalise_api/collections/translations.ex index 8abc72c..c5af649 100644 --- a/lib/elixir_lokalise_api/collections/translations.ex +++ b/lib/elixir_lokalise_api/collections/translations.ex @@ -5,5 +5,6 @@ defmodule ElixirLokaliseApi.Collection.Translations do total_count: nil, page_count: nil, per_page_limit: nil, - current_page: nil + current_page: nil, + next_cursor: nil end diff --git a/lib/elixir_lokalise_api/config.ex b/lib/elixir_lokalise_api/config.ex index 14f2317..63bea0b 100644 --- a/lib/elixir_lokalise_api/config.ex +++ b/lib/elixir_lokalise_api/config.ex @@ -37,7 +37,7 @@ defmodule ElixirLokaliseApi.Config do @doc """ Returns package version """ - def version, do: from_env(:version, "2.1.0") + def version, do: from_env(:version, "3.1.0") @doc """ Returns the base URL of the Lokalise APIv2 or OAuth2 diff --git a/lib/elixir_lokalise_api/processor.ex b/lib/elixir_lokalise_api/processor.ex index 4f7ba8c..9ecbc24 100644 --- a/lib/elixir_lokalise_api/processor.ex +++ b/lib/elixir_lokalise_api/processor.ex @@ -7,7 +7,8 @@ defmodule ElixirLokaliseApi.Processor do "x-pagination-total-count" => :total_count, "x-pagination-page-count" => :page_count, "x-pagination-limit" => :per_page_limit, - "x-pagination-page" => :current_page + "x-pagination-page" => :current_page, + "x-pagination-next-cursor" => :next_cursor } @doc """ @@ -102,8 +103,15 @@ defmodule ElixirLokaliseApi.Processor do acc [list | _] -> - {header_value, _} = list |> elem(1) |> Integer.parse() - acc |> Map.put(formatted_header, header_value) + header_value = list |> elem(1) + + parsed_value = + case Integer.parse(header_value) do + {number, _} -> number + :error -> header_value + end + + acc |> Map.put(formatted_header, parsed_value) end end) end diff --git a/mix.exs b/mix.exs index a8bdc1c..558cff3 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule ElixirLokaliseApi.MixProject do use Mix.Project @source_url "https://github.com/lokalise/elixir-lokalise-api" - @version "3.0.0" + @version "3.1.0" def project do [ @@ -44,9 +44,9 @@ defmodule ElixirLokaliseApi.MixProject do {:dialyxir, "~> 1.1", only: :dev, runtime: false}, {:httpoison, "~> 2.0"}, {:jason, "~> 1.2"}, - {:ex_doc, "~> 0.29.0", only: [:dev, :test]}, - {:exvcr, "~> 0.13.2", only: :test}, - {:excoveralls, "~> 0.15.0", only: :test} + {:ex_doc, "~> 0.32.2", only: [:dev, :test]}, + {:exvcr, "~> 0.15.1", only: :test}, + {:excoveralls, "~> 0.18.1", only: :test} ] end diff --git a/mix.lock b/mix.lock index ee50ebb..0e80a41 100644 --- a/mix.lock +++ b/mix.lock @@ -1,27 +1,27 @@ %{ - "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, + "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "certifi": {:hex, :certifi, "2.12.0", "2d1cca2ec95f59643862af91f001478c9863c2ac9cb6e2f89780bfd8de987329", [:rebar3], [], "hexpm", "ee68d85df22e554040cdb4be100f33873ac6051387baf6a8f6ce82272340ff1c"}, - "credo": {:hex, :credo, "1.7.1", "6e26bbcc9e22eefbff7e43188e69924e78818e2fe6282487d0703652bc20fd62", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "e9871c6095a4c0381c89b6aa98bc6260a8ba6addccf7f6a53da8849c748a58a2"}, - "dialyxir": {:hex, :dialyxir, "1.4.2", "764a6e8e7a354f0ba95d58418178d486065ead1f69ad89782817c296d0d746a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "516603d8067b2fd585319e4b13d3674ad4f314a5902ba8130cd97dc902ce6bbd"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.38", "b42252eddf63bda05554ba8be93a1262dc0920c721f1aaf989f5de0f73a2e367", [:mix], [], "hexpm", "2cd0907795aaef0c7e8442e376633c5b3bd6edc8dbbdc539b22f095501c1cdb6"}, + "credo": {:hex, :credo, "1.7.6", "b8f14011a5443f2839b04def0b252300842ce7388f3af177157c86da18dfbeea", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "146f347fb9f8cbc5f7e39e3f22f70acbef51d441baa6d10169dd604bfbc55296"}, + "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, - "ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"}, + "ex_doc": {:hex, :ex_doc, "0.32.2", "f60bbeb6ccbe75d005763e2a328e6f05e0624232f2393bc693611c2d3ae9fa0e", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "a4480305cdfe7fdfcbb77d1092c76161626d9a7aa4fb698aee745996e34602df"}, "exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], [], "hexpm", "1222419f706e01bfa1095aec9acf6421367dcfab798a6f67c54cf784733cd6b5"}, - "excoveralls": {:hex, :excoveralls, "0.15.3", "54bb54043e1cf5fe431eb3db36b25e8fd62cf3976666bafe491e3fa5e29eba47", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "f8eb5d8134d84c327685f7bb8f1db4147f1363c3c9533928234e496e3070114e"}, + "excoveralls": {:hex, :excoveralls, "0.18.1", "a6f547570c6b24ec13f122a5634833a063aec49218f6fff27de9df693a15588c", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d65f79db146bb20399f23046015974de0079668b9abb2f5aac074d078da60b8d"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm", "32e95820a97cffea67830e91514a2ad53b888850442d6d395f53a1ac60c82e07"}, - "exvcr": {:hex, :exvcr, "0.13.5", "3cb058c3a360bd0ff45d5e9f061723fad25e3a56157b76c0bbf20e8990470b14", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:httpoison, "~> 1.0 or ~> 2.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "89a7b951dd93ef735fbf2c83a552c962f2bdc9e1954fe355ac95c3128f285e8c"}, - "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, + "exvcr": {:hex, :exvcr, "0.15.1", "772db4d065f5136c6a984c302799a79e4ade3e52701c95425fa2229dd6426886", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:finch, "~> 0.16", [hex: :finch, repo: "hexpm", optional: true]}, {:httpoison, "~> 1.0 or ~> 2.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "de4fc18b1d672d9b72bc7468735e19779aa50ea963a1f859ef82cd9e294b13e3"}, + "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, "hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"}, - "httpoison": {:hex, :httpoison, "2.2.0", "839298929243b872b3f53c3693fa369ac3dbe03102cefd0a126194738bf4bb0e", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a49a9337c2b671464948a00cff6a882d271c1c8e3d25a6ca14d0532cbd23f65a"}, + "httpoison": {:hex, :httpoison, "2.2.1", "87b7ed6d95db0389f7df02779644171d7319d319178f6680438167d7b69b1f3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "51364e6d2f429d80e14fe4b5f8e39719cacd03eb3f9a9286e61e216feac2d2df"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm", "fc3499fed7a726995aa659143a248534adc754ebd16ccd437cd93b649a95091f"}, - "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"}, - "makeup_erlang": {:hex, :makeup_erlang, "0.1.2", "ad87296a092a46e03b7e9b0be7631ddcf64c790fa68a9ef5323b6cbb36affc72", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f3f5a1ca93ce6e092d92b6d9c049bcda58a3b617a8d888f8e7231c85630e8108"}, + "makeup": {:hex, :makeup, "1.1.2", "9ba8837913bdf757787e71c1581c21f9d2455f4dd04cfca785c70bbfff1a76a3", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cce1566b81fbcbd21eca8ffe808f33b221f9eee2cbc7a1706fc3da9ff18e6cac"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, + "makeup_erlang": {:hex, :makeup_erlang, "1.0.0", "6f0eff9c9c489f26b69b61440bf1b238d95badae49adac77973cbacae87e3c2e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "ea7a9307de9d1548d2a72d299058d1fd2339e3d398560a0e46c27dab4891e4d2"}, "meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, - "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "mimerl": {:hex, :mimerl, "1.3.0", "d0cd9fc04b9061f82490f6581e0128379830e78535e017f7780f37fea7545726", [:rebar3], [], "hexpm", "a1e15a50d1887217de95f0b9b0793e32853f7c258a5cd227650889b38839fe9d"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, diff --git a/test/elixir_lokalise_api/endpoints/keys_test.exs b/test/elixir_lokalise_api/endpoints/keys_test.exs index d6d2e27..125ef7f 100644 --- a/test/elixir_lokalise_api/endpoints/keys_test.exs +++ b/test/elixir_lokalise_api/endpoints/keys_test.exs @@ -13,6 +13,7 @@ defmodule ElixirLokaliseApi.KeysTest do doctest Keys @project_id "572560965f984614d567a4.18006942" + @project_id2 "2273827860c1e2473eb195.11207948" test "lists all keys" do use_cassette "keys_all" do @@ -51,6 +52,17 @@ defmodule ElixirLokaliseApi.KeysTest do end end + test "lists paginated with cursor keys" do + use_cassette "keys_find_cursor" do + {:ok, %KeysCollection{} = keys} = + Keys.all(@project_id2, limit: 2, pagination: "cursor", cursor: "eyIxIjozNzk3ODEzODh9") + + assert Enum.count(keys.items) == 2 + assert keys.per_page_limit == 2 + assert keys.next_cursor == "eyIxIjo0NTc4NDUxMDd9" + end + end + test "finds a key" do use_cassette "keys_find" do key_id = 79_039_609 diff --git a/test/elixir_lokalise_api/endpoints/translations_test.exs b/test/elixir_lokalise_api/endpoints/translations_test.exs index 2dd10ec..98e1d1a 100644 --- a/test/elixir_lokalise_api/endpoints/translations_test.exs +++ b/test/elixir_lokalise_api/endpoints/translations_test.exs @@ -13,6 +13,7 @@ defmodule ElixirLokaliseApi.TranslationsTest do doctest Translations @project_id "287061316050d93a27ada8.24068671" + @project_id2 "2273827860c1e2473eb195.11207948" test "lists all translations" do use_cassette "translations_all" do @@ -46,6 +47,21 @@ defmodule ElixirLokaliseApi.TranslationsTest do end end + test "lists paginated with cursor translations" do + use_cassette "translations_all_paginated_cursor" do + {:ok, %TranslationsCollection{} = translations} = + Translations.all(@project_id2, + limit: 2, + pagination: "cursor", + cursor: "eyIxIjozMDU0Mzg5ODQ0fQ==" + ) + + assert Enum.count(translations.items) == 2 + assert translations.per_page_limit == 2 + assert translations.next_cursor == "eyIxIjozMDU0Mzg5ODQ2fQ==" + end + end + test "finds a translation" do use_cassette "translation_find" do translation_id = 580_728_816 diff --git a/test/fixtures/cassettes/keys_find_cursor.json b/test/fixtures/cassettes/keys_find_cursor.json new file mode 100644 index 0000000..bd08c56 --- /dev/null +++ b/test/fixtures/cassettes/keys_find_cursor.json @@ -0,0 +1,45 @@ +[ + { + "request": { + "options": { + "recv_timeout": 5000, + "connect_timeout": 5000 + }, + "body": "", + "url": "https://api.lokalise.com/api2/projects/2273827860c1e2473eb195.11207948/keys?limit=2&pagination=cursor&cursor=eyIxIjozNzk3ODEzODh9", + "request_body": "", + "headers": { + "Accept": "application/json", + "User-Agent": "elixir-lokalise-api package/3.0.0", + "X-Api-Token": "***" + }, + "method": "get" + }, + "response": { + "binary": false, + "type": "ok", + "body": "{\"project_id\":\"2273827860c1e2473eb195.11207948\",\"branch\":\"master\",\"keys\":[{\"key_id\":395658713,\"created_at\":\"2023-10-17 12:38:06 (Etc\\/UTC)\",\"created_at_timestamp\":1697546286,\"key_name\":{\"ios\":\"sign_up\",\"android\":\"sign_up\",\"web\":\"sign_up\",\"other\":\"sign_up\"},\"filenames\":{\"ios\":\"\",\"android\":\"\",\"web\":\"\",\"other\":\"\"},\"description\":\"\",\"platforms\":[\"android\",\"web\"],\"tags\":[],\"is_plural\":false,\"plural_name\":\"\",\"is_hidden\":false,\"is_archived\":false,\"context\":\"\",\"base_words\":2,\"char_limit\":0,\"custom_attributes\":\"\",\"modified_at\":\"2023-10-17 12:38:06 (Etc\\/UTC)\",\"modified_at_timestamp\":1697546286,\"translations_modified_at\":\"2024-03-19 13:47:16 (Etc\\/UTC)\",\"translations_modified_at_timestamp\":1710856036},{\"key_id\":457845107,\"created_at\":\"2024-03-19 13:07:00 (Etc\\/UTC)\",\"created_at_timestamp\":1710853620,\"key_name\":{\"ios\":\"about:meta_desc\",\"android\":\"about:meta_desc\",\"web\":\"about:meta_desc\",\"other\":\"about:meta_desc\"},\"filenames\":{\"ios\":\"\",\"android\":\"\",\"web\":\"%LANG_ISO%.yml\",\"other\":\"\"},\"description\":\"\",\"platforms\":[\"web\"],\"tags\":[],\"is_plural\":false,\"plural_name\":\"\",\"is_hidden\":false,\"is_archived\":false,\"context\":\"\",\"base_words\":17,\"char_limit\":0,\"custom_attributes\":\"\",\"modified_at\":\"2024-03-19 13:07:00 (Etc\\/UTC)\",\"modified_at_timestamp\":1710853620,\"translations_modified_at\":\"2024-03-19 13:47:16 (Etc\\/UTC)\",\"translations_modified_at_timestamp\":1710856036}]}", + "headers": { + "Date": "Tue, 14 May 2024 18:23:27 GMT", + "Content-Type": "application/json", + "Transfer-Encoding": "chunked", + "Connection": "keep-alive", + "Server": "nginx", + "Vary": "Accept-Encoding", + "Cache-Control": "max-age=-172800, must-revalidate, no-cache, no-store, private", + "X-Pagination-Limit": "2", + "X-Pagination-Next-Cursor": "eyIxIjo0NTc4NDUxMDd9", + "pragma": "no-cache", + "X-Content-Type-Options": "nosniff", + "X-Frame-Options": "deny", + "X-XSS-Protection": "1; mode=block", + "Strict-Transport-Security": "max-age=31536000", + "Referrer-Policy": "origin", + "X-Lokalise-Process-Id": "7770f06c-414d-4e8b-93d0-112c2ea3792b", + "Expires": "Thu, 16 May 2024 18:23:27 GMT", + "Set-Cookie": "PHPSESSID=deleted; expires=Mon, 15-May-2023 18:23:26 GMT; Max-Age=0; path=/; httponly" + }, + "status_code": 200 + } + } +] \ No newline at end of file diff --git a/test/fixtures/cassettes/translations_all_paginated_cursor.json b/test/fixtures/cassettes/translations_all_paginated_cursor.json new file mode 100644 index 0000000..4b9cbf8 --- /dev/null +++ b/test/fixtures/cassettes/translations_all_paginated_cursor.json @@ -0,0 +1,45 @@ +[ + { + "request": { + "options": { + "recv_timeout": 5000, + "connect_timeout": 5000 + }, + "body": "", + "url": "https://api.lokalise.com/api2/projects/2273827860c1e2473eb195.11207948/translations?limit=2&pagination=cursor&cursor=eyIxIjozMDU0Mzg5ODQ0fQ%3D%3D", + "request_body": "", + "headers": { + "Accept": "application/json", + "User-Agent": "elixir-lokalise-api package/3.0.0", + "X-Api-Token": "***" + }, + "method": "get" + }, + "response": { + "binary": false, + "type": "ok", + "body": "{\"project_id\":\"2273827860c1e2473eb195.11207948\",\"branch\":\"master\",\"translations\":[{\"translation_id\":3054389845,\"segment_number\":1,\"key_id\":379781388,\"language_iso\":\"pl\",\"translation\":\"Zalogowa\\u0107 si\\u0119\",\"modified_by\":2,\"modified_by_email\":\"support@lokali.se\",\"modified_at\":\"2024-03-19 13:47:16 (Etc\\/UTC)\",\"modified_at_timestamp\":1710856036,\"is_reviewed\":false,\"reviewed_by\":0,\"is_unverified\":true,\"is_fuzzy\":true,\"words\":2,\"custom_translation_statuses\":[],\"task_id\":2259983},{\"translation_id\":3054389846,\"segment_number\":1,\"key_id\":379781388,\"language_iso\":\"en\",\"translation\":\"Sign in\",\"modified_by\":20181,\"modified_by_email\":\"bodrovis@protonmail.com\",\"modified_at\":\"2023-11-03 12:08:11 (Etc\\/UTC)\",\"modified_at_timestamp\":1699013291,\"is_reviewed\":false,\"reviewed_by\":0,\"is_unverified\":false,\"is_fuzzy\":false,\"words\":2,\"custom_translation_statuses\":[],\"task_id\":null}]}", + "headers": { + "Date": "Tue, 14 May 2024 18:38:49 GMT", + "Content-Type": "application/json", + "Transfer-Encoding": "chunked", + "Connection": "keep-alive", + "Server": "nginx", + "Vary": "Accept-Encoding", + "Cache-Control": "max-age=-172800, must-revalidate, no-cache, no-store, private", + "X-Pagination-Limit": "2", + "X-Pagination-Next-Cursor": "eyIxIjozMDU0Mzg5ODQ2fQ==", + "pragma": "no-cache", + "X-Content-Type-Options": "nosniff", + "X-Frame-Options": "deny", + "X-XSS-Protection": "1; mode=block", + "Strict-Transport-Security": "max-age=31536000", + "Referrer-Policy": "origin", + "X-Lokalise-Process-Id": "02b16ea4-b2f3-44c1-b998-037bc604dfa5", + "Expires": "Thu, 16 May 2024 18:38:49 GMT", + "Set-Cookie": "PHPSESSID=deleted; expires=Mon, 15-May-2023 18:38:48 GMT; Max-Age=0; path=/; httponly" + }, + "status_code": 200 + } + } +] \ No newline at end of file