From 9b3179feae39da18925c10b1903a1e908a629a61 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 20:18:45 +0200 Subject: [PATCH 01/24] migration: handle data handling in formatter by removing attribute access --- lib/strapi_ruby/formatter.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/strapi_ruby/formatter.rb b/lib/strapi_ruby/formatter.rb index dedd4a2..694aa49 100644 --- a/lib/strapi_ruby/formatter.rb +++ b/lib/strapi_ruby/formatter.rb @@ -20,9 +20,9 @@ def convert_to_datetime!(data) return unless StrapiRuby.config.convert_to_datetime if collection?(data) - data.each { |item| parse_into_datetime!(item.attributes) } + data.each { |item| parse_into_datetime!(item) } else - parse_into_datetime!(data.attributes) + parse_into_datetime!(data) end end @@ -62,9 +62,9 @@ def collection?(data) def convert_to_html!(data) if collection?(data) - data.each { |item| convert_attributes!(item.attributes) } + data.each { |item| convert_attributes!(item) } else - convert_attributes!(data.attributes) + convert_attributes!(data) end end From ead66608b482cec1f956355841d69ff907db6cab Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 20:19:07 +0200 Subject: [PATCH 02/24] migration: replace id by document_id in validations and builder --- lib/strapi_ruby/endpoint/builder.rb | 6 +++--- lib/strapi_ruby/validations.rb | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/strapi_ruby/endpoint/builder.rb b/lib/strapi_ruby/endpoint/builder.rb index 0cec14f..564f3f6 100644 --- a/lib/strapi_ruby/endpoint/builder.rb +++ b/lib/strapi_ruby/endpoint/builder.rb @@ -3,7 +3,7 @@ module Endpoint class Builder def initialize(options = {}) @resource = options[:resource] - @id = options[:id] + @document_id = options[:document_id] @query = Query.new(options).call @result = nil end @@ -20,7 +20,7 @@ def build_endpoint @result = if collection? "#{base_uri}/#{@resource}" else - "#{base_uri}/#{@resource}/#{@id}" + "#{base_uri}/#{@resource}/#{@document_id}" end end @@ -29,7 +29,7 @@ def append_query end def collection? - @id.nil? + @document_id.nil? end def base_uri diff --git a/lib/strapi_ruby/validations.rb b/lib/strapi_ruby/validations.rb index bbc5f4e..79ff24d 100644 --- a/lib/strapi_ruby/validations.rb +++ b/lib/strapi_ruby/validations.rb @@ -14,7 +14,7 @@ def validate_config(config) def validate_options(options) validate_config_presence validate_resource(options) - validate_id(options) + validate_document_id(options) validate_show_endpoint_params(options) validate_body(options) end @@ -47,8 +47,8 @@ def validate_resource(options) raise TypeError, "#{ErrorMessage.expected_string_symbol} Got #{options[:resource].class.name}" unless options[:resource].is_a?(String) || options[:resource].is_a?(Symbol) end - def validate_id(options) - raise TypeError, "#{ErrorMessage.expected_integer} Got #{options[:id].class.name}" if options.key?(:id) && !options[:id].is_a?(Integer) + def validate_document_id(options) + raise TypeError, "#{ErrorMessage.expected_integer} Got #{options[:document_id].class.name}" if options.key?(:document_id) && !options[:document_id].is_a?(String) end def validate_show_endpoint_params(options) From 4ef268ff7919d55048a4a74bb23fa29dd23b6d63 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 20:28:26 +0200 Subject: [PATCH 03/24] migration: update README to replace id with document_id in examples --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 85b88d5..6866501 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ data = answer.data meta = answer.meta # Access a specific attribute -answer = StrapiRuby.get(resource: :articles, id: 2) +answer = StrapiRuby.get(resource: :articles, document_id: "clkgylmcc000008lcdd868feh") article = answer.data title = article.attributes.title @@ -125,7 +125,7 @@ answer = StrapiRuby.get(resource: :restaurants) # Get a specific element -StrapiRuby.get(resource: :restaurants, id: 1) +StrapiRuby.get(resource: :restaurants, document_id: "clkgylmcc000008lcdd868feh") ``` #### .post @@ -143,7 +143,7 @@ StrapiRuby.post(resource: :articles, ```ruby # Update a specific item, return item updated StrapiRuby.put(resource: :articles, - id: 23, + document_id: "clkgylmcc000008lcdd868feh", data: {content: "'I've edited this article via a PUT request'"}) ``` @@ -151,7 +151,7 @@ StrapiRuby.put(resource: :articles, ```ruby # Delete an item, return item deleted -StrapiRuby.delete(resource: :articles, id: 12) +StrapiRuby.delete(resource: :articles, id: "clkgylmcc000008lcdd868feh") ``` @@ -324,11 +324,11 @@ StrapiRuby.get(resource: :users, filters: { username: { "$eq" => "John" } }) # Using $in operator to match multiples values StrapiRuby.get(resource: :restaurants, filters: { - id: { - "$in" => ["3", "6", "8"], + documentId: { + "$in" => ["clkgylmcc000008lcdd868feh", "clkgylw7d000108lc4rw1bb6s"], }, }) -# => /restaurants?filters[id][$in][0]=3&filters[id][$in][1]=6&filters[id][$in][2]=8 +# => /restaurants?filters[documentId][$in][0]=clkgylmcc000008lcdd868feh&filters[documentId][$in][0]=clkgylw7d000108lc4rw1bb6s # -------------------------------- From c7251bcc4f006c46082b0627653cb33508eecfac Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 20:29:52 +0200 Subject: [PATCH 04/24] migration: update integration tests to replace id with document_id and documentId (filters) for consistency --- spec/integration.rb | 109 ++++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 55 deletions(-) diff --git a/spec/integration.rb b/spec/integration.rb index d0d28cb..5b3d2de 100644 --- a/spec/integration.rb +++ b/spec/integration.rb @@ -24,7 +24,6 @@ def configure_strapi end end - # Test fetching all articles def test_get_all_articles test_get = StrapiRuby.get(resource: "articles") @@ -33,7 +32,7 @@ def test_get_all_articles # Test fetching one article def test_get_one_article - test_get = StrapiRuby.get(resource: "articles", id: 1) + test_get = StrapiRuby.get(resource: "articles", documentId: "1") test_get.data end @@ -53,32 +52,32 @@ def test_sorting # Test filtering def test_filtering - test_get = StrapiRuby.get(resource: "articles", fields: :title, filters: { id: { "$in" => ["1", "3"] } }) + test_get = StrapiRuby.get(resource: "articles", fields: :title, filters: { documentId: { "$in" => ["1", "3"] } }) test_get.data end # Test complex filtering def test_complex_filtering - test_get= StrapiRuby.get(resource: :books, - filters: { - "$or" => [ - { - date: { - "$eq" => "2020-01-01", - }, - }, - { - date: { - "$eq" => "2020-01-02", - }, - }, - ], - author: { - name: { - "$eq" => "Kai doe", - }, - }, - }) + test_get = StrapiRuby.get(resource: :books, + filters: { + "$or" => [ + { + date: { + "$eq" => "2020-01-01", + }, + }, + { + date: { + "$eq" => "2020-01-02", + }, + }, + ], + author: { + name: { + "$eq" => "Kai doe", + }, + }, + }) test_get.endpoint end @@ -130,14 +129,14 @@ def test_post_article # Test put article def test_put_article - id = StrapiRuby.get(resource: "articles", sort: "createdAt:asc").data.last.id - StrapiRuby.put(resource: "articles", id: id, data: { title: "Title has been changed by PUT request" }) + document_id = StrapiRuby.get(resource: "articles", sort: "createdAt:asc").data.last.id + StrapiRuby.put(resource: "articles", document_id: document_id, data: { title: "Title has been changed by PUT request" }) end # Test delete article def test_delete_article - id = StrapiRuby.get(resource: "articles", sort: "createdAt:asc").data.last.id - StrapiRuby.delete(resource: "articles", id: id) + document_id = StrapiRuby.get(resource: "articles", sort: "createdAt:asc").data.last.id + StrapiRuby.delete(resource: "articles", document_id: document_id) end def test_show_endpoint @@ -145,7 +144,7 @@ def test_show_endpoint end def test_escape_empty_answer - answer = StrapiRuby.get(resource: "articles", id: 233) + answer = StrapiRuby.get(resource: "articles", document_id: 233) StrapiRuby.escape_empty_answer(answer) do puts "if you see this, it means the test is not passing" @@ -156,17 +155,17 @@ def test_escape_empty_answer end def test_trigger_error_using_collection_parameters_on_single_endpoint - begin - StrapiRuby.get(resource: "articles", id: 1, page: 1) + begin + StrapiRuby.get(resource: "articles", document_id: 1, page: 1) rescue ArgumentError => e - puts e.message - puts "if you see this, it means the test is passing" + puts e.message + puts "if you see this, it means the test is passing" end - begin - StrapiRuby.get(resource: "articles", id: 1, filters: { id: { "$in" => ["1", "3"] } }) + begin + StrapiRuby.get(resource: "articles", document_id: 1, filters: { documentId: { "$in" => ["1", "3"] } }) rescue ArgumentError => e - puts e.message - puts "if you see this, it means the test is passing" + puts e.message + puts "if you see this, it means the test is passing" end end @@ -176,25 +175,25 @@ def test_trigger_error_using_collection_parameters_on_single_endpoint # Uncomment and run the desired test functions here tests = [ - # :test_get_all_articles, - # :test_get_one_article, - # :test_post_article, - # :test_put_article, - # :test_delete_article, - # :test_sorting, - # :test_filtering, - # :test_complex_filtering, - # :test_pagination, - # :test_offset_pagination, - # :test_locale, - # :test_selecting_fields, - # :test_populate, - # :test_raw_query, - # :test_404_endpoint, - # :test_show_endpoint, - # :test_escape_empty_answer, - # :test_trigger_error_using_collection_parameters_on_single_endpoint, -] + # :test_get_all_articles, + # :test_get_one_article, + # :test_post_article, + # :test_put_article, + # :test_delete_article, + # :test_sorting, + # :test_filtering, + # :test_complex_filtering, + # :test_pagination, + # :test_offset_pagination, + # :test_locale, + # :test_selecting_fields, + # :test_populate, + # :test_raw_query, + # :test_404_endpoint, + # :test_show_endpoint, + # :test_escape_empty_answer, + # :test_trigger_error_using_collection_parameters_on_single_endpoint, + ] tests.each do |test| puts "\n\n" From b342fdb15d5ce7bbf893ead04d3952bfdbc2f59f Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 20:35:09 +0200 Subject: [PATCH 05/24] missing example in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6866501..7d49a18 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ StrapiRuby.put(resource: :articles, ```ruby # Delete an item, return item deleted -StrapiRuby.delete(resource: :articles, id: "clkgylmcc000008lcdd868feh") +StrapiRuby.delete(resource: :articles, document_id: "clkgylmcc000008lcdd868feh") ``` From 6b09619dcdb16e04b62dce6bb74046631639dd5a Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 20:36:53 +0200 Subject: [PATCH 06/24] docs: V5 disclaimer --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 7d49a18..b4e257f 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,16 @@ I think it's one of the actual coolest solution for integrating a CMS into Rails for example, so let's dive in! +## Important Notice: Strapi V5 and strapi_ruby + +Starting from version >=1.0.0, the StrapiRuby gem is only compatible with Strapi version 5 and above. This update includes significant changes to align with the new response format introduced in Strapi v5. Key changes include: + +- **Flattened Response Format**: The `attributes` object has been removed, and fields are now directly part of the `data` object. +- **ID Handling**: The `id` field has been replaced with `documentId` to uniquely identify resources. +- **Filter Adjustments**: Filters that previously used `id` should now use `documentId`. + +These changes ensure that the StrapiRuby gem takes full advantage of the improvements in Strapi v5, providing a more streamlined and efficient API interaction experience. Please ensure your Strapi server is updated to version 5 or later to use this version of the gem. + ## Table of contents - [Installation](#installation) From 6a733f130919bd17b1ac65108f8519925fc2dc18 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 21:32:02 +0200 Subject: [PATCH 07/24] fix: clause guard to_html --- lib/strapi_ruby/markdown.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/strapi_ruby/markdown.rb b/lib/strapi_ruby/markdown.rb index 4aac905..5982c01 100644 --- a/lib/strapi_ruby/markdown.rb +++ b/lib/strapi_ruby/markdown.rb @@ -8,6 +8,8 @@ class Markdown include Singleton def to_html(markdown) + return "" if markdown.nil? + markdown_renderer.render(markdown) end From b6788cbf491b8c43efcf0202bda2f6f899e25760 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 21:35:09 +0200 Subject: [PATCH 08/24] migration: update client and formatter tests --- spec/client/client_spec.rb | 48 ++++++++++++++++---------------- spec/formatter/formatter_spec.rb | 46 +++++++++++++++--------------- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/spec/client/client_spec.rb b/spec/client/client_spec.rb index eca5db8..9d21e90 100644 --- a/spec/client/client_spec.rb +++ b/spec/client/client_spec.rb @@ -4,20 +4,20 @@ let(:client) { StrapiRuby::Client.new(strapi_server_uri: "https://www.example.com") } before do - stub_request(:get, "https://www.example.com/articles/1").to_return(status: 200, body: '{"data": {"attributes":{"id": 1, "title": "Example"}}}') - stub_request(:post, "https://www.example.com/articles").to_return(status: 200, body: '{"data": {"attributes": {"title": "This is a new example"}}}') - stub_request(:put, "https://www.example.com/articles/1").to_return(status: 200, body: '{"data": {"attributes": {"title": "This is a modified example"}}}') - stub_request(:delete, "https://www.example.com/articles/1").to_return(status: 200, body: '{"data": {"attributes": {"title": "This is a deleted example"}}}') + stub_request(:get, "https://www.example.com/articles/clkgylw7d000108lc4rw1bb6s").to_return(status: 200, body: '{"data" :{"documentId": "clkgylw7d000108lc4rw1bb6s", "title": "Example"}}') + stub_request(:post, "https://www.example.com/articles").to_return(status: 200, body: '{"data": {"documentId": "clkgylw7d000108lc4rw1bb6s", "title": "This is a new example"}}') + stub_request(:put, "https://www.example.com/articles/clkgylw7d000108lc4rw1bb6s").to_return(status: 200, body: '{"data": {"documentId": "clkgylw7d000108lc4rw1bb6s", "title": "This is a modified example"}}') + stub_request(:delete, "https://www.example.com/articles/clkgylw7d000108lc4rw1bb6s").to_return(status: 200, body: '{"data": {"documentId": "clkgylw7d000108lc4rw1bb6s", "title": "This is a deleted example"}}') end describe "#get" do it "sends a GET request to the specified endpoint" do - faraday_response = client.connection.get("/articles/1") + faraday_response = client.connection.get("/articles/clkgylw7d000108lc4rw1bb6s") expect(faraday_response.status).to eq(200) end it "returns an OpenStruct object" do - response = client.get("/articles/1") + response = client.get("/articles/clkgylw7d000108lc4rw1bb6s") expect(response.class).to eq(OpenStruct) end @@ -41,7 +41,7 @@ expect(faraday_response.status).to eq(200) response = client.post("/articles", { title: "This is a new example" }) p - expect(response.data.attributes.title).to eq("This is a new example") + expect(response.data.title).to eq("This is a new example") end it "returns an OpenStruct object" do @@ -65,57 +65,57 @@ describe "#put" do it "sends a PUT request to the specified endpoint" do - faraday_response = client.connection.put("/articles/1", { title: "This is a modified example" }) + faraday_response = client.connection.put("/articles/clkgylw7d000108lc4rw1bb6s", { title: "This is a modified example" }) expect(faraday_response.status).to eq(200) - response = client.put("/articles/1", { title: "This is a modified example" }) - expect(response.data.attributes.title).to eq("This is a modified example") + response = client.put("/articles/clkgylw7d000108lc4rw1bb6s", { title: "This is a modified example" }) + expect(response.data.title).to eq("This is a modified example") end it "returns an OpenStruct object" do - response = client.put("/articles/1", { title: "This is a modified example" }) + response = client.put("/articles/clkgylw7d000108lc4rw1bb6s", { title: "This is a modified example" }) expect(response.class).to eq(OpenStruct) end it "handles connection errors gracefully" do allow_any_instance_of(Faraday::Connection).to receive(:put).and_raise(Faraday::ConnectionFailed.new("Connection failed")) - expect { client.put("/resource/1", {}) }.to raise_error(StrapiRuby::ConnectionError) + expect { client.put("/resource/clkgylw7d000108lc4rw1bb6s", {}) }.to raise_error(StrapiRuby::ConnectionError) end it "handles timeout errors gracefully" do allow_any_instance_of(Faraday::Connection).to receive(:put).and_raise(Faraday::TimeoutError.new("Timeout Error")) - expect { client.put("/resource/1", {}) }.to raise_error(StrapiRuby::ConnectionError) + expect { client.put("/resource/clkgylw7d000108lc4rw1bb6s", {}) }.to raise_error(StrapiRuby::ConnectionError) end it "handles other errors gracefully" do allow_any_instance_of(Faraday::Connection).to receive(:put).and_raise(StandardError.new("Something bad happened")) - expect { client.put("/resource/1", {}) }.to raise_error(StrapiRuby::ConnectionError) + expect { client.put("/resource/clkgylw7d000108lc4rw1bb6s", {}) }.to raise_error(StrapiRuby::ConnectionError) end end describe "#delete" do it "sends a DELETE request to the specified endpoint" do - faraday_response = client.connection.delete("/articles/1") + faraday_response = client.connection.delete("/articles/clkgylw7d000108lc4rw1bb6s") expect(faraday_response.status).to eq(200) - response = client.delete("/articles/1") - expect(response.data.attributes.title).to eq("This is a deleted example") + response = client.delete("/articles/clkgylw7d000108lc4rw1bb6s") + expect(response.data.title).to eq("This is a deleted example") end it "returns an OpenStruct object" do - response = client.put("/articles/1", { title: "This is a deleted example" }) + response = client.put("/articles/clkgylw7d000108lc4rw1bb6s", { title: "This is a deleted example" }) expect(response.class).to eq(OpenStruct) end it "handles connection errors gracefully" do allow_any_instance_of(Faraday::Connection).to receive(:delete).and_raise(Faraday::ConnectionFailed.new("Connection failed")) - expect { client.delete("/resource/1") }.to raise_error(StrapiRuby::ConnectionError) + expect { client.delete("/resource/clkgylw7d000108lc4rw1bb6s") }.to raise_error(StrapiRuby::ConnectionError) end it "handles timeout errors gracefully" do allow_any_instance_of(Faraday::Connection).to receive(:delete).and_raise(Faraday::TimeoutError.new("Timeout Error")) - expect { client.delete("/resource/1") }.to raise_error(StrapiRuby::ConnectionError) + expect { client.delete("/resource/clkgylw7d000108lc4rw1bb6s") }.to raise_error(StrapiRuby::ConnectionError) end it "handles other errors gracefully" do allow_any_instance_of(Faraday::Connection).to receive(:delete).and_raise(StandardError.new("Something bad happened")) - expect { client.delete("/resource/1") }.to raise_error(StrapiRuby::ConnectionError) + expect { client.delete("/resource/clkgylw7d000108lc4rw1bb6s") }.to raise_error(StrapiRuby::ConnectionError) end end @@ -146,15 +146,15 @@ describe "#handle_response" do context "when the response status is 200" do - let(:response) { double(status: 200, message: "OK", body: '{"data": {"id": 1, "name": "Example"}}') } + let(:response) { double(status: 200, message: "OK", body: '{"data": {"documentId": "clkgylw7d000108lc4rw1bb6s", "title": "Example"}}') } it "returns an OpenStruct object" do expect(client.send(:handle_response, response)).to be_a(OpenStruct) end it "parses the JSON data into the OpenStruct object" do - expect(client.send(:handle_response, response).data.id).to eq(1) - expect(client.send(:handle_response, response).data.name).to eq("Example") + expect(client.send(:handle_response, response).data.documentId).to eq("clkgylw7d000108lc4rw1bb6s") + expect(client.send(:handle_response, response).data.title).to eq("Example") end end diff --git a/spec/formatter/formatter_spec.rb b/spec/formatter/formatter_spec.rb index 705cec1..1a49994 100644 --- a/spec/formatter/formatter_spec.rb +++ b/spec/formatter/formatter_spec.rb @@ -3,53 +3,52 @@ RSpec.describe StrapiRuby::Formatter do before do html_value = "

Mocked content

\n" - allow(attributes).to receive(:content).and_return(html_value) - allow(attributes).to receive(:content=).with(html_value) + allow(data).to receive(:content).and_return(html_value) + allow(data).to receive(:content=).with(html_value) end describe "#convert_to_html!" do let(:convert_to_html_keys) { [:content] } - let(:attributes) { double("attributes", content: "Mocked content", title: "# Mocked title") } - let(:data) { double("data", attributes: attributes) } + let(:data) { OpenStruct.new(content: "Mocked content", title: "# Mocked title") } let(:data_collection) { [data, data] } let(:empty_data) { OpenStruct.new } let(:formatter) { StrapiRuby::Formatter.new({ convert_to_html: convert_to_html_keys }) } + context "when data is a single item" do context "and when the key matches" do it "should convert data to HTML" do converted_content = "

Mocked content

\n" - converted_data = data - formatter.send(:convert_to_html!, converted_data) - expect(converted_data.attributes.content).to eq(converted_content) + formatter.send(:convert_to_html!, data) + expect(data.content).to eq(converted_content) end end + context "and when the key does not match" do - it "should not convert data to HTML if data.attributes.key is the same" do + it "should not convert data to HTML if data.key is the same" do converted_title = "

Mocked title

\n" - converted_data = data - formatter.send(:convert_to_html!, converted_data) - expect(converted_data.attributes.title).not_to eq(converted_title) + formatter.send(:convert_to_html!, data) + expect(data.title).not_to eq(converted_title) end end end + context "when data is a collection" do context "and when the key matches" do it "should convert each data to HTML" do converted_content = "

Mocked content

\n" - converted_data_collection = data_collection - formatter.send(:convert_to_html!, converted_data_collection) - converted_data_collection.each do |converted_data| - expect(converted_data.attributes.content).to eq(converted_content) + formatter.send(:convert_to_html!, data_collection) + data_collection.each do |converted_data| + expect(converted_data.content).to eq(converted_content) end end end + context "and when the key does not match" do it "should not convert each data to HTML" do converted_title = "

Mocked title

\n" - converted_data_collection = data_collection - formatter.send(:convert_to_html!, converted_data_collection) - converted_data_collection.each do |converted_data| - expect(converted_data.attributes.title).not_to eq(converted_title) + formatter.send(:convert_to_html!, data_collection) + data_collection.each do |converted_data| + expect(converted_data.title).not_to eq(converted_title) end end end @@ -58,23 +57,22 @@ describe "#convert_to_datetime!" do let(:formatter) { StrapiRuby::Formatter.new } - let(:attributes) { OpenStruct.new(createdAt: "2023-10-04T12:34:56.000Z", updatedAt: "2023-10-04T13:45:30.000Z", publishedAt: "2023-10-04T14:56:12.000Z") } - let(:data) { double("data", attributes: attributes) } + let(:data) { OpenStruct.new(createdAt: "2023-10-04T12:34:56.000Z", updatedAt: "2023-10-04T13:45:30.000Z", publishedAt: "2023-10-04T14:56:12.000Z") } context "when data contain ISO date strings" do it "parses createdAt attribute into DateTime" do formatter.send(:convert_to_datetime!, data) - expect(data.attributes.createdAt).to be_a(DateTime) + expect(data.createdAt).to be_a(DateTime) end it "parses updatedAt attribute into DateTime" do formatter.send(:convert_to_datetime!, data) - expect(data.attributes.updatedAt).to be_a(DateTime) + expect(data.updatedAt).to be_a(DateTime) end it "parses publishedAt attribute into DateTime" do formatter.send(:convert_to_datetime!, data) - expect(data.attributes.publishedAt).to be_a(DateTime) + expect(data.publishedAt).to be_a(DateTime) end end end From 8df074e60fefe2f11c66315fbeca9b80750df612 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 22:08:55 +0200 Subject: [PATCH 09/24] fix: add OpenStruct requirement to strapi_ruby.rb --- lib/strapi_ruby.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/strapi_ruby.rb b/lib/strapi_ruby.rb index 1543d51..efb28ac 100644 --- a/lib/strapi_ruby.rb +++ b/lib/strapi_ruby.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +require "ostruct" require_relative "strapi_ruby/version" require_relative "strapi_ruby/validations" From 503df6519fd2ce51f14808b95497048a62837c8e Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 22:18:48 +0200 Subject: [PATCH 10/24] fix: update response status handling in StrapiRuby client --- lib/strapi_ruby/client.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/strapi_ruby/client.rb b/lib/strapi_ruby/client.rb index 25bafe6..bc0b1d2 100644 --- a/lib/strapi_ruby/client.rb +++ b/lib/strapi_ruby/client.rb @@ -71,7 +71,7 @@ def build_data_payload(body) def handle_response(response) body = convert_json_to_open_struct(response.body) case response.status - when 200 + when 200..204 body when 400 raise BadRequestError.new(body.error.message, response.status) From c23a688539e96e2c344bfd2faeca58cecacc71b7 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 22:29:21 +0200 Subject: [PATCH 11/24] migration: update integration tests to use documentId instead of id for article resource --- spec/integration.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/integration.rb b/spec/integration.rb index 5b3d2de..0db4b5a 100644 --- a/spec/integration.rb +++ b/spec/integration.rb @@ -129,13 +129,13 @@ def test_post_article # Test put article def test_put_article - document_id = StrapiRuby.get(resource: "articles", sort: "createdAt:asc").data.last.id + document_id = StrapiRuby.get(resource: "articles", sort: "createdAt:asc").data.last.documentId StrapiRuby.put(resource: "articles", document_id: document_id, data: { title: "Title has been changed by PUT request" }) end # Test delete article def test_delete_article - document_id = StrapiRuby.get(resource: "articles", sort: "createdAt:asc").data.last.id + document_id = StrapiRuby.get(resource: "articles", sort: "createdAt:asc").data.last.documentId StrapiRuby.delete(resource: "articles", document_id: document_id) end @@ -177,9 +177,9 @@ def test_trigger_error_using_collection_parameters_on_single_endpoint tests = [ # :test_get_all_articles, # :test_get_one_article, - # :test_post_article, - # :test_put_article, - # :test_delete_article, + # :test_post_article, + # :test_put_article, + :test_delete_article, # :test_sorting, # :test_filtering, # :test_complex_filtering, From 71320c2d48636f5c24e8da7e6a45747661321021 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 22:29:39 +0200 Subject: [PATCH 12/24] fix: add nil checks for response body and answer data in StrapiRuby client --- lib/strapi_ruby/client.rb | 4 ++-- lib/strapi_ruby/interface.rb | 4 ++-- lib/strapi_ruby/validations.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/strapi_ruby/client.rb b/lib/strapi_ruby/client.rb index bc0b1d2..cfcd950 100644 --- a/lib/strapi_ruby/client.rb +++ b/lib/strapi_ruby/client.rb @@ -69,9 +69,9 @@ def build_data_payload(body) # rubocop:disable Metrics/AbcSize def handle_response(response) - body = convert_json_to_open_struct(response.body) + body = convert_json_to_open_struct(response.body) unless response.body.empty? case response.status - when 200..204 + when 200, 201 body when 400 raise BadRequestError.new(body.error.message, response.status) diff --git a/lib/strapi_ruby/interface.rb b/lib/strapi_ruby/interface.rb index a020961..2d4280b 100644 --- a/lib/strapi_ruby/interface.rb +++ b/lib/strapi_ruby/interface.rb @@ -30,8 +30,8 @@ def request(http_verb, options = {}) validate_options(options) @endpoint = build_endpoint(options) answer = build_answer(http_verb, @endpoint, options) - data = format_data(answer.data, options) - meta = answer.meta + data = format_data(answer.data, options) unless answer.data.nil? + meta = answer.meta unless answer.meta.nil? return_success_open_struct(data, meta, options) rescue StrapiRuby::ClientError, StrapiRuby::ConfigurationError => e diff --git a/lib/strapi_ruby/validations.rb b/lib/strapi_ruby/validations.rb index 79ff24d..15dce5e 100644 --- a/lib/strapi_ruby/validations.rb +++ b/lib/strapi_ruby/validations.rb @@ -48,7 +48,7 @@ def validate_resource(options) end def validate_document_id(options) - raise TypeError, "#{ErrorMessage.expected_integer} Got #{options[:document_id].class.name}" if options.key?(:document_id) && !options[:document_id].is_a?(String) + raise TypeError, "#{ErrorMessage.expected_string} Got #{options[:document_id].class.name}" if options.key?(:document_id) && !options[:document_id].is_a?(String) end def validate_show_endpoint_params(options) From 87ef6567692f12a42738927c34a11edb5d4af946 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 22:33:16 +0200 Subject: [PATCH 13/24] fix: add nil check for answer before processing data and meta in StrapiRuby client --- lib/strapi_ruby/interface.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/strapi_ruby/interface.rb b/lib/strapi_ruby/interface.rb index 2d4280b..52f6a22 100644 --- a/lib/strapi_ruby/interface.rb +++ b/lib/strapi_ruby/interface.rb @@ -30,8 +30,10 @@ def request(http_verb, options = {}) validate_options(options) @endpoint = build_endpoint(options) answer = build_answer(http_verb, @endpoint, options) - data = format_data(answer.data, options) unless answer.data.nil? - meta = answer.meta unless answer.meta.nil? + if answer + data = format_data(answer.data, options) unless answer.data.nil? + meta = answer.meta unless answer.meta.nil? + end return_success_open_struct(data, meta, options) rescue StrapiRuby::ClientError, StrapiRuby::ConfigurationError => e From ec58c2e88c532d4106a017a24b070ad8b669754c Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 22:46:15 +0200 Subject: [PATCH 14/24] fix: add nil value check in StrapiRuby parameters to prevent CGI.escape errors --- lib/strapi_ruby/endpoint/strapi_parameters.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/strapi_ruby/endpoint/strapi_parameters.rb b/lib/strapi_ruby/endpoint/strapi_parameters.rb index 45cb914..b9b8ff1 100644 --- a/lib/strapi_ruby/endpoint/strapi_parameters.rb +++ b/lib/strapi_ruby/endpoint/strapi_parameters.rb @@ -117,6 +117,10 @@ def traverse_hash(hash, parent_key = nil) # We can pass values as symbols but we need to convert them to string # to be able to escape them value = value.to_s if value.is_a?(Symbol) + # We throw an error if the value is nil because it will break the CGI.escape method + if value.nil? + raise ArgumentError, "#{ErrorMessage.expected_string} Got #{value.class.name}" + end "#{current_key}=#{CGI.escape(value)}" end end.join("&") From 0b373ceaee104fdb4380011e3cacdff51bc92c43 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 23:02:22 +0200 Subject: [PATCH 15/24] refactor: remove debug print statement from StrapiRuby configuration spec --- spec/config/config_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/config/config_spec.rb b/spec/config/config_spec.rb index b57aaf6..ec3f194 100644 --- a/spec/config/config_spec.rb +++ b/spec/config/config_spec.rb @@ -17,7 +17,6 @@ config.strapi_server_uri = "https://example.com" config.strapi_token = "124" config.faraday = faraday_string - p config expect { config.call }.to raise_error(TypeError) end end From d080f4a6e86b2ae8c0afc6c8c79d9b2f8f7fe98d Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 23:36:21 +0200 Subject: [PATCH 16/24] refactor: skip nil values in StrapiRuby parameters to improve CGI.escape handling --- lib/strapi_ruby/endpoint/strapi_parameters.rb | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/strapi_ruby/endpoint/strapi_parameters.rb b/lib/strapi_ruby/endpoint/strapi_parameters.rb index b9b8ff1..ce7cd5b 100644 --- a/lib/strapi_ruby/endpoint/strapi_parameters.rb +++ b/lib/strapi_ruby/endpoint/strapi_parameters.rb @@ -114,16 +114,11 @@ def traverse_hash(hash, parent_key = nil) traverse_hash({ index => item }, current_key) end else - # We can pass values as symbols but we need to convert them to string - # to be able to escape them value = value.to_s if value.is_a?(Symbol) - # We throw an error if the value is nil because it will break the CGI.escape method - if value.nil? - raise ArgumentError, "#{ErrorMessage.expected_string} Got #{value.class.name}" - end + next if value.nil? # Skip nil values "#{current_key}=#{CGI.escape(value)}" end - end.join("&") + end.compact.join("&") end end end From 98c6b9990a3b177b89ffebf444c07cf6abc28a1a Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Wed, 9 Apr 2025 23:38:11 +0200 Subject: [PATCH 17/24] refactor: use FlatParamsEncoder in StrapiRuby client to prevent double encoding of special characters --- lib/strapi_ruby/client.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/strapi_ruby/client.rb b/lib/strapi_ruby/client.rb index cfcd950..fe6ad97 100644 --- a/lib/strapi_ruby/client.rb +++ b/lib/strapi_ruby/client.rb @@ -40,7 +40,8 @@ def set_connection(options, &block) "User-Agent" => "StrapiRuby/#{StrapiRuby::VERSION}" } Faraday.new(url: url) do |faraday| - faraday.request :url_encoded + # Use FlatParamsEncoder to prevent double encoding of special characters + faraday.options.params_encoder = Faraday::FlatParamsEncoder faraday.adapter Faraday.default_adapter block&.call(faraday) faraday.headers = default_headers.merge(faraday.headers) From 9bfb2b552ec2daf553edc479acd6ce358d7a64aa Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Thu, 10 Apr 2025 00:15:08 +0200 Subject: [PATCH 18/24] migrate integration tests --- spec/integration.rb | 203 +++++++++++++++++++++++++++++--------------- 1 file changed, 136 insertions(+), 67 deletions(-) diff --git a/spec/integration.rb b/spec/integration.rb index 0db4b5a..d6a5fef 100644 --- a/spec/integration.rb +++ b/spec/integration.rb @@ -27,99 +27,183 @@ def configure_strapi # Test fetching all articles def test_get_all_articles test_get = StrapiRuby.get(resource: "articles") - test_get.data + test_get end # Test fetching one article def test_get_one_article test_get = StrapiRuby.get(resource: "articles", documentId: "1") - test_get.data + test_get end # Test pagination def test_pagination + # Create 4 articles + first_article = StrapiRuby.post(resource: "articles", data: { title: "This is my first article", content: "This is some dummy content" }) + second_article = StrapiRuby.post(resource: "articles", data: { title: "This is my second article", content: "This is some dummy content" }) + third_article = StrapiRuby.post(resource: "articles", data: { title: "This is my third article", content: "This is some dummy content" }) + fourth_article = StrapiRuby.post(resource: "articles", data: { title: "This is my fourth article", content: "This is some dummy content" }) test_get = StrapiRuby.get(resource: "articles", page: 1, page_size: 2) - test_get.data.count + p "test_pagination: #{test_get.data.count == 2}" + # Delete the articles + StrapiRuby.delete(resource: "articles", document_id: first_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: second_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: third_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: fourth_article.data.documentId) end # Test sorting def test_sorting test_get = StrapiRuby.get(resource: "articles", sort: ["createdAt:desc", "title:asc"]) test_get.data.map do |item| - item.attributes.createdAt + item.createdAt end + # data should be sorted by createdAt descending and title ascending + # the first item should have the highest createdAt and the lowest title + first_item = test_get.data.first + last_item = test_get.data.last + p "test_sorting: #{first_item.createdAt > last_item.createdAt}" + p "test_sorting: #{first_item.title < last_item.title}" end # Test filtering def test_filtering - test_get = StrapiRuby.get(resource: "articles", fields: :title, filters: { documentId: { "$in" => ["1", "3"] } }) + # Make sure we have at least 3 articles: this test is dependent on the test_post_article test and test_delete_article test + first_article = StrapiRuby.post(resource: "articles", data: { title: "This is my fourth article", content: "This is some dummy content" }) + second_article = StrapiRuby.post(resource: "articles", data: { title: "This is my fifth article", content: "This is some dummy content" }) + third_article = StrapiRuby.post(resource: "articles", data: { title: "This is my sixth article", content: "This is some dummy content" }) + + test_get = StrapiRuby.get(resource: "articles", fields: :title, filters: { documentId: { "$in" => [first_article.data.documentId, third_article.data.documentId] } }) test_get.data + p "test_filtering: #{test_get.data.count == 2}" + # delete the articles + StrapiRuby.delete(resource: "articles", document_id: first_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: third_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: second_article.data.documentId) end # Test complex filtering def test_complex_filtering - test_get = StrapiRuby.get(resource: :books, + # Create an article with the following data: + first_article = StrapiRuby.post(resource: "articles", data: { title: "Babar", content: "Aventure au pays des éléphants" }) + second_article = StrapiRuby.post(resource: "articles", data: { title: "Tintin", content: "Objectif lune" }) + third_article = StrapiRuby.post(resource: "articles", data: { title: "Astérix", content: "La table des dieux" }) + fourth_article = StrapiRuby.post(resource: "articles", data: { title: "Batman", content: "Gotham ne deviendra pas une victime" }) + + # Adjust the filters to match the fields in your articles + test_get = StrapiRuby.get(resource: :articles, filters: { "$or" => [ { - date: { - "$eq" => "2020-01-01", + title: { + "$eq" => "Babar", }, }, { - date: { - "$eq" => "2020-01-02", + title: { + "$eq" => "Tintin", # Tintin }, }, - ], - author: { - name: { - "$eq" => "Kai doe", + { + content: { + "$eq" => "Gotham ne deviendra pas une victime", # Aventure au pays des éléphants + }, }, - }, + ], }) - test_get.endpoint + + p "test_complex_filtering: #{test_get.data.count == 3}" + + test_get_2 = StrapiRuby.get(resource: :articles, + filters: { + "$or" => [ + { title: { "$eq" => "Batman" } }, + { title: { "$eq" => "Tintin" } }, + ], + content: { + "$eq" => "Gotham ne deviendra pas une victime", + }, + }) + + p "test_complex_filtering_2: #{test_get_2.data.count == 1}" + + # Delete the articles + StrapiRuby.delete(resource: "articles", document_id: first_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: second_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: third_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: fourth_article.data.documentId) end # Test raw query def test_raw_query - test_get = StrapiRuby.get(resource: "articles", raw: "?fields=title&sort=createdAt:asc") - test_get.data.map do |item| - item.attributes.title - end + first_article = StrapiRuby.post(resource: "articles", data: { title: "This is my first article", content: "This is some dummy content" }) + second_article = StrapiRuby.post(resource: "articles", data: { title: "This is my second article", content: "This is some dummy content" }) + third_article = StrapiRuby.post(resource: "articles", data: { title: "This is my third article", content: "This is some dummy content" }) + test_get = StrapiRuby.get(resource: "articles", raw: "?fields=title&sort=createdAt:desc") + p "test_raw_query: #{test_get.data.count == 3}" + p "test_raw_query: #{test_get.data.first.title == "This is my third article"}" + p "test_raw_query: #{test_get.data.last.title == "This is my first article"}" + + StrapiRuby.delete(resource: "articles", document_id: first_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: second_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: third_article.data.documentId) end # Test offset pagination def test_offset_pagination - test_get = StrapiRuby.get(resource: "articles", start: 0, limit: 1) + # Create 4 articles + first_article = StrapiRuby.post(resource: "articles", data: { title: "This is my first article", content: "This is some dummy content" }) + second_article = StrapiRuby.post(resource: "articles", data: { title: "This is my second article", content: "This is some dummy content" }) + third_article = StrapiRuby.post(resource: "articles", data: { title: "This is my third article", content: "This is some dummy content" }) + fourth_article = StrapiRuby.post(resource: "articles", data: { title: "This is my fourth article", content: "This is some dummy content" }) + test_get = StrapiRuby.get(resource: "articles", start: 2, limit: 1) test_get.data + p "test_offset_pagination: #{test_get.data.count == 1}" + # delete the articles + StrapiRuby.delete(resource: "articles", document_id: first_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: second_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: third_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: fourth_article.data.documentId) end -# Test locale +# Test locale: this won't work if you don't create the local on strapi in settings then enable it in on your collection type advanced settings def test_locale - test_get = StrapiRuby.get(resource: "articles", locale: :en) + first_article = StrapiRuby.post(resource: "articles", data: { title: "This is my japanese article", content: "some japanese content", locale: "ja" }) + second_article = StrapiRuby.post(resource: "articles", data: { title: "This is my italian article", content: "some italian content", locale: "it" }) + test_get = StrapiRuby.get(resource: "articles", locale: "ja") + test_get.data + p "test_locale: #{test_get.data.count == 1}" + test_get = StrapiRuby.get(resource: "articles", locale: "it") test_get.data + p "test_locale: #{test_get.data.count == 1}" + # delete the articles + StrapiRuby.delete(resource: "articles", document_id: first_article.data.documentId) + StrapiRuby.delete(resource: "articles", document_id: second_article.data.documentId) end # Test selecting fields def test_selecting_fields + first_article = StrapiRuby.post(resource: "articles", data: { title: "This is my first article", content: "This is some dummy content" }) test_get = StrapiRuby.get(resource: :articles, fields: [:title]) - test_get.data + # Should not contain content field + p "test_selecting_fields: #{test_get.data.first.content.nil?}" + p "test_selecting_fields: #{!test_get.data.first.title.nil? && !test_get.data.first.title.empty?}" + # Delete the article + StrapiRuby.delete(resource: "articles", document_id: first_article.data.documentId) end -# Test populate +# Test populate: add featuredMedia field to the article and see if its populated def test_populate + first_article = StrapiRuby.post(resource: "articles", data: { title: "This is my first article", content: "This is some dummy content" }) test_get = StrapiRuby.get(resource: :articles, populate: :*) - test_get.data.first.attributes.featuredMedia + test_get.data.first.featuredMedia + # Delete the article + StrapiRuby.delete(resource: "articles", document_id: first_article.data.documentId) end -# Test a 404 endpoint +# Test a 404 endpoint: this will fail poorly def test_404_endpoint answer = StrapiRuby.get(resource: "thisDoesNotExist") - { error: answer.error, - data: answer.data, - meta: answer.meta } - # p test_get.data.count end # Test post article @@ -140,11 +224,12 @@ def test_delete_article end def test_show_endpoint - StrapiRuby.get(resource: "articles", show_endpoint: true).endpoint + endpoint = StrapiRuby.get(resource: "articles", filters: { documentId: { "$in" => ["someId", "someOtherId"] } }, show_endpoint: true).endpoint + p "test_show_endpoint: #{endpoint.include?("http://localhost:1337/api/articles?filters[documentId][$in][0]=someId&filters[documentId][$in][1]=someOtherId")}" end def test_escape_empty_answer - answer = StrapiRuby.get(resource: "articles", document_id: 233) + answer = StrapiRuby.get(resource: "articles", document_id: "thisDoesNotExist") StrapiRuby.escape_empty_answer(answer) do puts "if you see this, it means the test is not passing" @@ -154,46 +239,30 @@ def test_escape_empty_answer answer end -def test_trigger_error_using_collection_parameters_on_single_endpoint - begin - StrapiRuby.get(resource: "articles", document_id: 1, page: 1) - rescue ArgumentError => e - puts e.message - puts "if you see this, it means the test is passing" - end - begin - StrapiRuby.get(resource: "articles", document_id: 1, filters: { documentId: { "$in" => ["1", "3"] } }) - rescue ArgumentError => e - puts e.message - puts "if you see this, it means the test is passing" - end -end - # Main execution configure_strapi puts "\n\n" # Uncomment and run the desired test functions here tests = [ - # :test_get_all_articles, - # :test_get_one_article, - # :test_post_article, - # :test_put_article, - :test_delete_article, - # :test_sorting, - # :test_filtering, - # :test_complex_filtering, - # :test_pagination, - # :test_offset_pagination, - # :test_locale, - # :test_selecting_fields, - # :test_populate, - # :test_raw_query, - # :test_404_endpoint, - # :test_show_endpoint, - # :test_escape_empty_answer, - # :test_trigger_error_using_collection_parameters_on_single_endpoint, - ] + :test_post_article, + :test_get_all_articles, + :test_get_one_article, + :test_put_article, + :test_delete_article, + :test_sorting, + :test_filtering, + :test_complex_filtering, + :test_pagination, + :test_offset_pagination, + :test_locale, + :test_selecting_fields, + :test_populate, + :test_raw_query, + :test_404_endpoint, + :test_show_endpoint, + :test_escape_empty_answer, +] tests.each do |test| puts "\n\n" From ff91fcad1166a6344475db790cf2cf26c05f2b10 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Thu, 10 Apr 2025 00:24:04 +0200 Subject: [PATCH 19/24] docs: fix README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b4e257f..4d431ef 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ Starting from version >=1.0.0, the StrapiRuby gem is only compatible with Strapi These changes ensure that the StrapiRuby gem takes full advantage of the improvements in Strapi v5, providing a more streamlined and efficient API interaction experience. Please ensure your Strapi server is updated to version 5 or later to use this version of the gem. +Following will be the documentation for 1.xx release. + ## Table of contents - [Installation](#installation) @@ -60,8 +62,6 @@ Add this line to your application's Gemfile: gem "strapi_ruby" ``` - - Then if you use Rails, run in your terminal to generate a config initializer. Otherwise copy paste and fill the config block. ```bash @@ -117,7 +117,7 @@ meta = answer.meta # Access a specific attribute answer = StrapiRuby.get(resource: :articles, document_id: "clkgylmcc000008lcdd868feh") article = answer.data -title = article.attributes.title +title = article.title # If an error occur, it will be raised to be rescued and displayed in the answer. data = answer.data # => nil @@ -186,7 +186,7 @@ end
    <% @articles.data.each do |article| %>
  • - <%= article.attributes.title %> + <%= article.title %>
  • <% end %>
From fcb6ef3e0fd689779a1d2bf6a548edebe1c7e2e1 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Thu, 10 Apr 2025 23:27:44 +0200 Subject: [PATCH 20/24] chore: bump version to 1.0.0 in StrapiRuby module --- lib/strapi_ruby/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/strapi_ruby/version.rb b/lib/strapi_ruby/version.rb index 286a7b5..b8830d8 100644 --- a/lib/strapi_ruby/version.rb +++ b/lib/strapi_ruby/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module StrapiRuby - VERSION = "0.1.4" + VERSION = "1.0.0" end From 31a01ae160f84d7c9709c94bda9f2d3032caa407 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Thu, 10 Apr 2025 23:28:28 +0200 Subject: [PATCH 21/24] docs: update Gemfile entry for strapi_ruby to specify version constraint '~> 1.0.0' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d431ef..7631a33 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ Add this line to your application's Gemfile: ```ruby # Gemfile - gem "strapi_ruby" + gem "strapi_ruby" '~> 1.0.0' ``` Then if you use Rails, run in your terminal to generate a config initializer. Otherwise copy paste and fill the config block. From 9994ecb80443c48a7f7cbe2985bfa3bc16345b54 Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Thu, 10 Apr 2025 23:33:28 +0200 Subject: [PATCH 22/24] fix: updated gemfile.lock --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0404d7f..d8a7fae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - strapi_ruby (0.1.4) + strapi_ruby (1.0.0) colorize (~> 1.1.0) faraday (~> 2.7) redcarpet (~> 3.6) From 81aa97662bf32fa38d0112011c5526599fc6693e Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Thu, 10 Apr 2025 23:36:27 +0200 Subject: [PATCH 23/24] fix: update gemfile.lock --- Gemfile.lock | 2 +- lib/strapi_ruby/version.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index d8a7fae..5f3a970 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - strapi_ruby (1.0.0) + strapi_ruby (1.0.1) colorize (~> 1.1.0) faraday (~> 2.7) redcarpet (~> 3.6) diff --git a/lib/strapi_ruby/version.rb b/lib/strapi_ruby/version.rb index b8830d8..6e9e599 100644 --- a/lib/strapi_ruby/version.rb +++ b/lib/strapi_ruby/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module StrapiRuby - VERSION = "1.0.0" + VERSION = "1.0.1" end From 3d8e569581cbbb7a2ad129183154eb7fe28e96dd Mon Sep 17 00:00:00 2001 From: Maxence Robinet Date: Thu, 10 Apr 2025 23:37:16 +0200 Subject: [PATCH 24/24] docs: update Gemfile entry for strapi_ruby to specify version constraint '~> 1.0.1' --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7631a33..5f7b8e2 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,11 @@ Following will be the documentation for 1.xx release. ## Installation -Add this line to your application's Gemfile: +Add this line to your application's Gemfile - **make sure to take at least 1.0.1 version** ```ruby # Gemfile - gem "strapi_ruby" '~> 1.0.0' + gem 'strapi_ruby', '~> 1.0.1' ``` Then if you use Rails, run in your terminal to generate a config initializer. Otherwise copy paste and fill the config block.