From 9b0e5f9e7deaf791d01a2f8bbf7889f504173431 Mon Sep 17 00:00:00 2001 From: meili-bot <74670311+meili-bot@users.noreply.github.com> Date: Mon, 6 Dec 2021 14:23:34 +0100 Subject: [PATCH 01/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa883abe..12d1556d 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ JSON output: ## 🤖 Compatibility with MeiliSearch -This package only guarantees the compatibility with the [version v0.24.0 of MeiliSearch](https://github.com/meilisearch/MeiliSearch/releases/tag/v0.24.0). +This package only guarantees the compatibility with the [version v0.25.0 of MeiliSearch](https://github.com/meilisearch/MeiliSearch/releases/tag/v0.25.0). ## 💡 Learn More From de3e4815812d38a348b848a82075e4223973fba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Mon, 13 Dec 2021 14:24:43 +0100 Subject: [PATCH 02/14] Use Authorization header instead of X-Meili-API-Key (#275) --- lib/meilisearch/http_request.rb | 2 +- spec/meilisearch/index/base_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/meilisearch/http_request.rb b/lib/meilisearch/http_request.rb index d7a72905..125ab5a3 100644 --- a/lib/meilisearch/http_request.rb +++ b/lib/meilisearch/http_request.rb @@ -62,7 +62,7 @@ def http_delete(relative_path = '') def build_default_options_headers(api_key = nil) { 'Content-Type' => 'application/json', - 'X-Meili-API-Key' => api_key + 'Authorization' => "Bearer #{api_key}" }.compact end diff --git a/spec/meilisearch/index/base_spec.rb b/spec/meilisearch/index/base_spec.rb index 93681cf6..a1ef77ee 100644 --- a/spec/meilisearch/index/base_spec.rb +++ b/spec/meilisearch/index/base_spec.rb @@ -99,7 +99,7 @@ expect(MeiliSearch::Index).to receive(:get).with( "#{URL}/indexes/options", { - headers: { 'X-Meili-API-Key' => MASTER_KEY }, + headers: { 'Authorization' => "Bearer #{MASTER_KEY}" }, body: 'null', query: {}, max_retries: 1, From 8893955c444bf61c49e209e0f822a1e379956fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Tue, 14 Dec 2021 18:41:39 +0100 Subject: [PATCH 03/14] Changes related to the new task API (#276) * First verison of the new task API * Create task.rb * Fix linter error * Add tests for client.wait_for_task * Fix linter errors --- .code-samples.meilisearch.yaml | 4 +- .rubocop_todo.yml | 10 +- README.md | 4 +- lib/meilisearch.rb | 1 + lib/meilisearch/client.rb | 64 ++- lib/meilisearch/index.rb | 83 ++- lib/meilisearch/task.rb | 43 ++ spec/meilisearch/client/indexes_spec.rb | 139 +++-- spec/meilisearch/client/keys_spec.rb | 7 +- spec/meilisearch/client/requests_spec.rb | 12 +- spec/meilisearch/client/tasks_spec.rb | 127 +++++ spec/meilisearch/index/base_spec.rb | 93 ++-- spec/meilisearch/index/documents_spec.rb | 381 +++++++------- .../index/search/attributes_to_crop_spec.rb | 7 +- .../index/search/facets_distribution_spec.rb | 2 +- spec/meilisearch/index/search/filter_spec.rb | 2 +- .../index/search/multi_params_spec.rb | 6 +- spec/meilisearch/index/search/offset_spec.rb | 2 +- spec/meilisearch/index/search/q_spec.rb | 2 +- spec/meilisearch/index/search/sort_spec.rb | 4 +- spec/meilisearch/index/settings_spec.rb | 491 ++++++++++-------- spec/meilisearch/index/updates_spec.rb | 75 --- spec/support/books_contexts.rb | 4 +- 23 files changed, 894 insertions(+), 669 deletions(-) create mode 100644 lib/meilisearch/task.rb create mode 100644 spec/meilisearch/client/tasks_spec.rb delete mode 100644 spec/meilisearch/index/updates_spec.rb diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 31e44544..02f07f27 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -44,9 +44,9 @@ delete_documents_1: |- search_post_1: |- client.index('movies').search('american ninja') get_update_1: |- - client.index('movies').get_update_status(1) + client.index('movies').task(1) get_all_updates_1: |- - client.index('movies').get_all_update_status + client.index('movies').tasks get_keys_1: |- client.keys get_settings_1: |- diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 520f743e..c52bc2f1 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2021-11-21 21:31:55 UTC using RuboCop version 1.23.0. +# on 2021-12-13 22:26:31 UTC using RuboCop version 1.23.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -20,23 +20,23 @@ Layout/HeredocIndentation: Exclude: - 'spec/meilisearch/index/documents_spec.rb' -# Offense count: 32 +# Offense count: 33 # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods. # IgnoredMethods: refine Metrics/BlockLength: - Max: 512 + Max: 557 # Offense count: 1 # Configuration parameters: CountComments, CountAsOne. Metrics/ClassLength: - Max: 289 + Max: 278 # Offense count: 1 # Configuration parameters: Max, CountKeywordArgs. Metrics/ParameterLists: MaxOptionalParameters: 4 -# Offense count: 2 +# Offense count: 1 Naming/AccessorMethodName: Exclude: - 'lib/meilisearch/index.rb' diff --git a/README.md b/README.md index 12d1556d..be4ca717 100644 --- a/README.md +++ b/README.md @@ -92,10 +92,10 @@ documents = [ { id: 6, title: 'Philadelphia', genres: ['Drama'] }, ] # If the index 'movies' does not exist, MeiliSearch creates it when you first add the documents. -index.add_documents(documents) # => { "updateId": 0 } +index.add_documents(documents) # => { "uid": 0 } ``` -With the `updateId`, you can check the status (`enqueued`, `processing`, `processed` or `failed`) of your documents addition using the [update endpoint](https://docs.meilisearch.com/reference/api/updates.html#get-an-update-status). +With the `uid`, you can check the status (`enqueued`, `processing`, `succeeded` or `failed`) of your documents addition using the [update endpoint](https://docs.meilisearch.com/reference/api/updates.html#get-an-update-status). 💡 To customize the `Client`, for example, increasing the default timeout, please check out [this section](https://github.com/meilisearch/meilisearch-ruby/wiki/Client-Options) of the Wiki. diff --git a/lib/meilisearch.rb b/lib/meilisearch.rb index 3289517c..f3e165c8 100644 --- a/lib/meilisearch.rb +++ b/lib/meilisearch.rb @@ -2,6 +2,7 @@ require 'meilisearch/version' require 'meilisearch/utils' +require 'meilisearch/task' require 'meilisearch/client' require 'meilisearch/index' diff --git a/lib/meilisearch/client.rb b/lib/meilisearch/client.rb index 71f8ec2d..26ceb7bf 100644 --- a/lib/meilisearch/client.rb +++ b/lib/meilisearch/client.rb @@ -22,35 +22,41 @@ def indexes def create_index(index_uid, options = {}) body = Utils.transform_attributes(options.merge(uid: index_uid)) - index_hash = http_post '/indexes', body - index_object(index_hash['uid'], index_hash['primaryKey']) + http_post '/indexes', body end - def get_or_create_index(index_uid, options = {}) - begin - index_instance = fetch_index(index_uid) - rescue ApiError => e - raise e unless e.code == 'index_not_found' - - index_instance = create_index(index_uid, options) - end - index_instance + # Synchronous version of create_index. + # Waits for the task to be achieved, be careful when using it. + def create_index!(index_uid, options = {}) + task = create_index(index_uid, options) + wait_for_task(task['uid']) end + # def get_or_create_index(index_uid, options = {}) + # begin + # index_instance = fetch_index(index_uid) + # rescue ApiError => e + # raise e unless e.code == 'index_not_found' + + # index_instance = create_index(index_uid, options) + # end + # index_instance + # end + def delete_index(index_uid) index_object(index_uid).delete end - # Usage: - # client.delete_index_if_exists('indexUID') - def delete_index_if_exists(index_uid) - index_object(index_uid).delete - true - rescue ApiError => e - raise e if e.code != 'index_not_found' + # # Usage: + # # client.delete_index_if_exists('indexUID') + # def delete_index_if_exists(index_uid) + # index_object(index_uid).delete + # true + # rescue ApiError => e + # raise e if e.code != 'index_not_found' - false - end + # false + # end # Usage: # client.index('indexUID') @@ -107,10 +113,28 @@ def dump_status(dump_uid) end alias get_dump_status dump_status + ### TASKS + + def tasks + task_endpoint.global_tasks + end + + def task(task_uid) + task_endpoint.global_task(task_uid) + end + + def wait_for_task(task_uid, timeout_in_ms = 5000, interval_in_ms = 50) + task_endpoint.wait_for_task(task_uid, timeout_in_ms, interval_in_ms) + end + private def index_object(uid, primary_key = nil) Index.new(uid, @base_url, @api_key, primary_key, @options) end + + def task_endpoint + Task.new(@base_url, @api_key, @options) + end end end diff --git a/lib/meilisearch/index.rb b/lib/meilisearch/index.rb index d7d3fd31..ca9ecb7d 100644 --- a/lib/meilisearch/index.rb +++ b/lib/meilisearch/index.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true require 'meilisearch/http_request' -require 'timeout' module MeiliSearch class Index < HTTPRequest attr_reader :uid, :primary_key, :created_at, :updated_at def initialize(index_uid, url, api_key = nil, primary_key = nil, options = {}) + @url = url @uid = index_uid @primary_key = primary_key super(url, api_key, options) @@ -31,10 +31,7 @@ def fetch_raw_info end def update(body) - index_hash = http_put indexes_path(id: @uid), Utils.transform_attributes(body) - set_base_properties index_hash - - self + http_put indexes_path(id: @uid), Utils.transform_attributes(body) end alias update_index update @@ -78,8 +75,8 @@ def add_documents(documents, primary_key = nil) alias add_or_replace_documents add_documents def add_documents!(documents, primary_key = nil) - update = add_documents(documents, primary_key) - wait_for_pending_update(update['updateId']) + task = add_documents(documents, primary_key) + wait_for_task(task['uid']) end alias replace_documents! add_documents! alias add_or_replace_documents! add_documents! @@ -112,41 +109,41 @@ def update_documents(documents, primary_key = nil) alias add_or_update_documents update_documents def update_documents!(documents, primary_key = nil) - update = update_documents(documents, primary_key) - wait_for_pending_update(update['updateId']) + task = update_documents(documents, primary_key) + wait_for_task(task['uid']) end alias add_or_update_documents! update_documents! def add_documents_in_batches(documents, batch_size = 1000, primary_key = nil) - update_ids = [] + tasks = [] documents.each_slice(batch_size) do |batch| - update_ids.append(add_documents(batch, primary_key)) + tasks.append(add_documents(batch, primary_key)) end - update_ids + tasks end def add_documents_in_batches!(documents, batch_size = 1000, primary_key = nil) - update_ids = add_documents_in_batches(documents, batch_size, primary_key) + tasks = add_documents_in_batches(documents, batch_size, primary_key) responses = [] - update_ids.each do |update_object| - responses.append(wait_for_pending_update(update_object['updateId'])) + tasks.each do |task_obj| + responses.append(wait_for_task(task_obj['uid'])) end responses end def update_documents_in_batches(documents, batch_size = 1000, primary_key = nil) - update_ids = [] + tasks = [] documents.each_slice(batch_size) do |batch| - update_ids.append(update_documents(batch, primary_key)) + tasks.append(update_documents(batch, primary_key)) end - update_ids + tasks end def update_documents_in_batches!(documents, batch_size = 1000, primary_key = nil) - update_ids = update_documents_in_batches(documents, batch_size, primary_key) + tasks = update_documents_in_batches(documents, batch_size, primary_key) responses = [] - update_ids.each do |update_object| - responses.append(wait_for_pending_update(update_object['updateId'])) + tasks.each do |task_obj| + responses.append(wait_for_task(task_obj['uid'])) end responses end @@ -161,8 +158,8 @@ def delete_documents(documents_ids) alias delete_multiple_documents delete_documents def delete_documents!(documents_ids) - update = delete_documents(documents_ids) - wait_for_pending_update(update['updateId']) + task = delete_documents(documents_ids) + wait_for_task(task['uid']) end alias delete_multiple_documents! delete_documents! @@ -173,8 +170,8 @@ def delete_document(document_id) alias delete_one_document delete_document def delete_document!(document_id) - update = delete_document(document_id) - wait_for_pending_update(update['updateId']) + task = delete_document(document_id) + wait_for_task(task['uid']) end alias delete_one_document! delete_document! @@ -183,8 +180,8 @@ def delete_all_documents end def delete_all_documents! - update = delete_all_documents - wait_for_pending_update(update['updateId']) + task = delete_all_documents + wait_for_task(task['uid']) end ### SEARCH @@ -195,31 +192,23 @@ def search(query, options = {}) http_post "/indexes/#{@uid}/search", parsed_options end - ### UPDATES + ### TASKS - def get_update_status(update_id) - http_get "/indexes/#{@uid}/updates/#{update_id}" + def task_endpoint + Task.new(@url, @api_key, @options) end + private :task_endpoint - def get_all_update_status - http_get "/indexes/#{@uid}/updates" + def task(task_uid) + task_endpoint.index_task(@uid, task_uid) end - def achieved_upate?(update) - update['status'] != 'enqueued' && update['status'] != 'processing' + def tasks + task_endpoint.index_tasks(@uid) end - def wait_for_pending_update(update_id, timeout_in_ms = 5000, interval_in_ms = 50) - Timeout.timeout(timeout_in_ms.to_f / 1000) do - loop do - get_update = get_update_status(update_id) - return get_update if achieved_upate?(get_update) - - sleep interval_in_ms.to_f / 1000 - end - end - rescue Timeout::Error - raise MeiliSearch::TimeoutError + def wait_for_task(task_uid, timeout_in_ms = 5000, interval_in_ms = 50) + task_endpoint.wait_for_task(task_uid, timeout_in_ms, interval_in_ms) end ### STATS @@ -236,10 +225,6 @@ def indexing? stats['isIndexing'] end - def last_update - stats['lastUpdate'] - end - def field_distribution stats['fieldDistribution'] end diff --git a/lib/meilisearch/task.rb b/lib/meilisearch/task.rb new file mode 100644 index 00000000..4d0af45a --- /dev/null +++ b/lib/meilisearch/task.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'meilisearch/http_request' +require 'timeout' + +module MeiliSearch + class Task < HTTPRequest + def global_tasks + http_get '/tasks/' + end + + def global_task(task_uid) + http_get "/tasks/#{task_uid}" + end + + def index_tasks(index_uid) + http_get "/indexes/#{index_uid}/tasks" + end + + def index_task(index_uid, task_uid) + http_get "/indexes/#{index_uid}/tasks/#{task_uid}" + end + + def wait_for_task(task_uid, timeout_in_ms = 5000, interval_in_ms = 50) + Timeout.timeout(timeout_in_ms.to_f / 1000) do + loop do + task = global_task(task_uid) + return task if achieved_task?(task) + + sleep interval_in_ms.to_f / 1000 + end + end + rescue Timeout::Error + raise MeiliSearch::TimeoutError + end + + private + + def achieved_task?(task) + task['status'] != 'enqueued' && task['status'] != 'processing' + end + end +end diff --git a/spec/meilisearch/client/indexes_spec.rb b/spec/meilisearch/client/indexes_spec.rb index 7e2b7a10..2b6f5bfd 100644 --- a/spec/meilisearch/client/indexes_spec.rb +++ b/spec/meilisearch/client/indexes_spec.rb @@ -4,19 +4,47 @@ describe '#create_index' do context 'without a primary key' do it 'creates an index' do - index = client.create_index('new_index') + task = client.create_index('new_index') + expect(task['type']).to eq('indexCreation') + client.wait_for_task(task['uid']) + index = client.fetch_index('new_index') + expect(index).to be_a(MeiliSearch::Index) + expect(index.uid).to eq('new_index') + expect(index.primary_key).to be_nil + end + + it 'creates an index synchronously' do + task = client.create_index!('new_index') + expect(task['type']).to eq('indexCreation') + expect(task['status']).to eq('succeeded') + + index = client.fetch_index('new_index') expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('new_index') expect(index.primary_key).to be_nil - expect(index.fetch_primary_key).to be_nil end end context 'with a primary key' do it 'creates an index' do - index = client.create_index('new_index', primaryKey: 'primary_key') + task = client.create_index('new_index', primaryKey: 'primary_key') + expect(task['type']).to eq('indexCreation') + client.wait_for_task(task['uid']) + + index = client.fetch_index('new_index') + expect(index).to be_a(MeiliSearch::Index) + expect(index.uid).to eq('new_index') + expect(index.primary_key).to eq('primary_key') + expect(index.fetch_primary_key).to eq('primary_key') + end + + it 'creates an index synchronously' do + task = client.create_index!('new_index', primaryKey: 'primary_key') + expect(task['type']).to eq('indexCreation') + expect(task['status']).to eq('succeeded') + index = client.fetch_index('new_index') expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('new_index') expect(index.primary_key).to eq('primary_key') @@ -25,8 +53,11 @@ context 'when primary key option in snake_case' do it 'creates an index' do - index = client.create_index('new_index', primary_key: 'primary_key') + task = client.create_index('new_index', primary_key: 'primary_key') + expect(task['type']).to eq('indexCreation') + client.wait_for_task(task['uid']) + index = client.fetch_index('new_index') expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('new_index') expect(index.primary_key).to eq('primary_key') @@ -36,12 +67,15 @@ context 'when uid is provided as an option' do it 'ignores the uid option' do - index = client.create_index( + task = client.create_index( 'new_index', primaryKey: 'primary_key', uid: 'not_primary_key' ) + expect(task['type']).to eq('indexCreation') + client.wait_for_task(task['uid']) + index = client.fetch_index('new_index') expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('new_index') expect(index.primary_key).to eq('primary_key') @@ -51,12 +85,14 @@ end context 'when an index with a given uid already exists' do - it 'raises an error' do - client.create_index('existing_index') - - expect do - client.create_index('existing_index') - end.to raise_meilisearch_api_error_with(409, 'index_already_exists', 'invalid_request') + it 'returns a failing task' do + task1 = client.create_index!('existing_index') + task2 = client.create_index!('existing_index') + expect(task1['type']).to eq('indexCreation') + expect(task2['type']).to eq('indexCreation') + expect(task1['status']).to eq('succeeded') + expect(task2['status']).to eq('failed') + expect(task2['error']['code']).to eq('index_already_exists') end end @@ -69,49 +105,47 @@ end end - describe '#get_or_create_index' do - it 'creates a new index' do - expect do - new_index = client.get_or_create_index('new_index') + # describe '#get_or_create_index' do + # it 'creates a new index' do + # expect do + # new_index = client.get_or_create_index('new_index') - expect(new_index).to be_a(MeiliSearch::Index) - end.to change { client.indexes.length }.by(1) + # expect(new_index).to be_a(MeiliSearch::Index) + # end.to change { client.indexes.length }.by(1) - found_index = client.fetch_index('new_index') - expect(found_index.uid).to eq('new_index') - expect(found_index.primary_key).to be_nil - end + # found_index = client.fetch_index('new_index') + # expect(found_index.uid).to eq('new_index') + # expect(found_index.primary_key).to be_nil + # end - it 'gets an index that already exists' do - client.create_index('existing_index') + # it 'gets an index that already exists' do + # client.create_index('existing_index') - expect do - client.get_or_create_index('existing_index') - end.not_to(change { client.indexes.length }) - end + # expect do + # client.get_or_create_index('existing_index') + # end.not_to(change { client.indexes.length }) + # end - context 'when a primary key is provided' do - it 'creates a new index' do - expect do - index = client.get_or_create_index('new_index', primaryKey: 'primary_key') + # context 'when a primary key is provided' do + # it 'creates a new index' do + # expect do + # index = client.get_or_create_index('new_index', primaryKey: 'primary_key') - expect(index).to be_a(MeiliSearch::Index) - end.to change { client.indexes.length }.by(1) - end - end - end + # expect(index).to be_a(MeiliSearch::Index) + # end.to change { client.indexes.length }.by(1) + # end + # end + # end describe '#indexes' do it 'returns MeiliSearch::Index objects' do - client.create_index('index') - - response = client.indexes.first - - expect(response).to be_a(MeiliSearch::Index) + client.create_index!('index') + index = client.indexes.first + expect(index).to be_a(MeiliSearch::Index) end it 'gets a list of indexes' do - ['first_index', 'second_index', 'third_index'].each { |name| client.create_index(name) } + ['first_index', 'second_index', 'third_index'].each { |name| client.create_index!(name) } indexes = client.indexes @@ -124,7 +158,7 @@ describe '#raw_indexes' do it 'returns raw indexes' do - client.create_index('index') + client.create_index!('index') response = client.raw_indexes.first @@ -133,7 +167,7 @@ end it 'gets a list of raw indexes' do - ['first_index', 'second_index', 'third_index'].each { |name| client.create_index(name) } + ['first_index', 'second_index', 'third_index'].each { |name| client.create_index!(name) } indexes = client.raw_indexes @@ -146,7 +180,7 @@ describe '#fetch_index' do it 'fetches index by uid' do - client.create_index('new_index', primaryKey: 'primary_key') + client.create_index!('new_index', primaryKey: 'primary_key') fetched_index = client.fetch_index('new_index') @@ -159,8 +193,9 @@ describe '#fetch_raw_index' do it 'fetch a specific index raw Hash response based on uid' do - index = client.create_index('specific_index_fetch_raw', primaryKey: 'primary_key') + client.create_index!('specific_index_fetch_raw', primaryKey: 'primary_key') + index = client.fetch_index('specific_index_fetch_raw') raw_response = index.fetch_raw_info expect(raw_response).to be_a(Hash) @@ -175,7 +210,7 @@ describe '#index' do it 'returns an index object with the provided uid' do - client.create_index('existing_index', primaryKey: 'primary_key') + client.create_index!('existing_index', primaryKey: 'primary_key') # this index is in memory, without metadata from server index = client.index('existing_index') @@ -193,16 +228,20 @@ describe '#delete_index' do context 'when the index exists' do it 'deletes the index' do - client.create_index('existing_index') + client.create_index!('existing_index') + + task = client.delete_index('existing_index') + expect(task['type']).to eq('indexDeletion') + achieved_task = client.wait_for_task(task['uid']) - expect(client.delete_index('existing_index')).to be_nil + expect(achieved_task['status']).to eq('succeeded') expect { client.fetch_index('existing_index') }.to raise_index_not_found_meilisearch_api_error end end context 'when the index does not exist' do it 'raises an index not found error' do - expect { client.delete_index('index_does_not_exist') }.to raise_index_not_found_meilisearch_api_error + expect { client.fetch_index('index_does_not_exist') }.to raise_index_not_found_meilisearch_api_error end end end diff --git a/spec/meilisearch/client/keys_spec.rb b/spec/meilisearch/client/keys_spec.rb index 932e32b8..e9b04453 100644 --- a/spec/meilisearch/client/keys_spec.rb +++ b/spec/meilisearch/client/keys_spec.rb @@ -36,9 +36,8 @@ it 'succeeds to search when using public key' do uid = random_uid public_key = client.keys['public'] - index = client.create_index(uid) - response = index.add_documents(title: 'Test') - index.wait_for_pending_update(response['updateId']) + index = client.index(uid) + index.add_documents!(title: 'Test') new_client = MeiliSearch::Client.new(URL, public_key) response = new_client.index(uid).search('test') @@ -47,7 +46,7 @@ it 'succeeds to get settings when using private key' do uid = random_uid - client.create_index(uid) + client.create_index!(uid) private_key = client.keys['private'] new_client = MeiliSearch::Client.new(URL, private_key) response = new_client.index(uid).settings diff --git a/spec/meilisearch/client/requests_spec.rb b/spec/meilisearch/client/requests_spec.rb index afa10f26..630f9458 100644 --- a/spec/meilisearch/client/requests_spec.rb +++ b/spec/meilisearch/client/requests_spec.rb @@ -10,10 +10,18 @@ end it 'parses options when they are in a snake_case' do - client.create_index(key, primary_key: key) + client.create_index!(key, primary_key: key) + + index = client.fetch_index(key) + expect(index.uid).to eq(key) + expect(index.primary_key).to eq(key) end it 'parses options when they are in a different shape' do - client.create_index(key, priMARy_kEy: key) + client.create_index!(key, priMARy_kEy: key) + + index = client.fetch_index(key) + expect(index.uid).to eq(key) + expect(index.primary_key).to eq(key) end end diff --git a/spec/meilisearch/client/tasks_spec.rb b/spec/meilisearch/client/tasks_spec.rb new file mode 100644 index 00000000..02dc955c --- /dev/null +++ b/spec/meilisearch/client/tasks_spec.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +RSpec.describe 'MeiliSearch::Tasks' do + include_context 'search books with genre' + + # Ensure there is at least 1 task + before do + task = index.add_documents!(documents) + @task_uid = task['uid'] + end + + it 'gets a task of an index' do + task = index.task(@task_uid) + expect(task).to be_a(Hash) + expect(task['uid']).to eq(@task_uid) + expect(task).to have_key('status') + expect(task).to have_key('indexUid') + expect(task).to have_key('type') + end + + it 'gets all the tasks of an index' do + tasks = index.tasks + expect(tasks['results']).to be_a(Array) + expect(tasks['results'].first).to have_key('uid') + expect(tasks['results'].first).to have_key('status') + expect(tasks['results'].first).to have_key('indexUid') + expect(tasks['results'].first).to have_key('type') + end + + it 'gets a task of the MeiliSearch instance' do + task = client.task(0) + expect(task).to be_a(Hash) + expect(task['uid']).to eq(0) + expect(task).to have_key('status') + expect(task).to have_key('indexUid') + expect(task).to have_key('type') + end + + it 'gets all the tasks of the MeiliSearch instance' do + tasks = client.tasks + expect(tasks['results']).to be_a(Array) + expect(tasks['results'].first).to have_key('uid') + expect(tasks['results'].first).to have_key('status') + expect(tasks['results'].first).to have_key('indexUid') + expect(tasks['results'].first).to have_key('type') + end + + describe '#index.wait_for_task' do + it 'waits for task with default values' do + task = index.add_documents(documents) + task = index.wait_for_task(task['uid']) + + expect(task).to be_a(Hash) + expect(task['status']).not_to eq('enqueued') + end + + it 'waits for task with default values after several updates' do + index.add_documents(documents) + index.add_documents(documents) + index.add_documents(documents) + index.add_documents(documents) + index.add_documents(documents) + task = index.add_documents(documents) + status = index.wait_for_task(task['uid']) + expect(status).to be_a(Hash) + expect(status['status']).not_to eq('enqueued') + end + + it 'waits for task with custom timeout_in_ms and raises MeiliSearchTimeoutError' do + index.add_documents(documents) + task = index.add_documents(documents) + expect do + index.wait_for_task(task['uid'], 1) + end.to raise_error(MeiliSearch::TimeoutError) + end + + it 'waits for task with custom interval_in_ms and raises Timeout::Error' do + index.add_documents(documents) + task = index.add_documents(documents) + expect do + Timeout.timeout(0.1) do + index.wait_for_task(task['uid'], 5000, 200) + end + end.to raise_error(Timeout::Error) + end + end + + describe '#client.wait_for_task' do + it 'waits for task with default values' do + task = index.add_documents!(documents) + task = client.wait_for_task(task['uid']) + + expect(task).to be_a(Hash) + expect(task['status']).not_to eq('enqueued') + end + + it 'waits for task with default values after several updates' do + index.add_documents(documents) + index.add_documents(documents) + index.add_documents(documents) + index.add_documents(documents) + index.add_documents(documents) + task = index.add_documents(documents) + status = client.wait_for_task(task['uid']) + expect(status).to be_a(Hash) + expect(status['status']).not_to eq('enqueued') + end + + it 'waits for task with custom timeout_in_ms and raises MeiliSearchTimeoutError' do + index.add_documents(documents) + task = index.add_documents(documents) + expect do + client.wait_for_task(task['uid'], 1) + end.to raise_error(MeiliSearch::TimeoutError) + end + + it 'waits for task with custom interval_in_ms and raises Timeout::Error' do + index.add_documents(documents) + task = index.add_documents(documents) + expect do + Timeout.timeout(0.1) do + client.wait_for_task(task['uid'], 5000, 200) + end + end.to raise_error(Timeout::Error) + end + end +end diff --git a/spec/meilisearch/index/base_spec.rb b/spec/meilisearch/index/base_spec.rb index a1ef77ee..5c15e33a 100644 --- a/spec/meilisearch/index/base_spec.rb +++ b/spec/meilisearch/index/base_spec.rb @@ -2,8 +2,9 @@ RSpec.describe MeiliSearch::Index do it 'fetch the info of the index' do - index = client.create_index('new_index') - index.fetch_info + client.create_index!('new_index') + + index = client.fetch_index('new_index') expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('new_index') expect(index.created_at).to be_a(Time) @@ -14,7 +15,7 @@ end it 'fetch the raw Hash info of the index' do - client.create_index('specific_index_fetch_raw', primaryKey: 'primary_key') + client.create_index!('specific_index_fetch_raw', primaryKey: 'primary_key') raw_index = client.fetch_raw_index('specific_index_fetch_raw') @@ -28,25 +29,36 @@ end it 'get primary-key of index if null' do - index = client.create_index('index_without_primary_key') + client.create_index!('index_without_primary_key') + + index = client.fetch_index('index_without_primary_key') expect(index.primary_key).to be_nil expect(index.fetch_primary_key).to be_nil end it 'get primary-key of index if it exists' do - index = client.create_index('index_with_prirmary_key', primaryKey: 'primary_key') + client.create_index!('index_with_prirmary_key', primaryKey: 'primary_key') + + index = client.fetch_index('index_with_prirmary_key') expect(index.primary_key).to eq('primary_key') expect(index.fetch_primary_key).to eq('primary_key') end it 'get uid of index' do - index = client.create_index('uid') + client.create_index!('uid') + + index = client.fetch_index('uid') expect(index.uid).to eq('uid') end it 'updates primary-key of index if not defined before' do - index = client.create_index('uid', primaryKey: 'primary_key') - index.update(primaryKey: 'new_primary_key') + client.create_index!('uid') + + task = client.index('uid').update(primaryKey: 'new_primary_key') + expect(task['type']).to eq('indexUpdate') + client.wait_for_task(task['uid']) + + index = client.fetch_index('uid') expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('uid') expect(index.primary_key).to eq('new_primary_key') @@ -58,8 +70,13 @@ end it 'updates primary-key of index if has been defined before but there is not docs' do - index = client.create_index('uid') - index.update(primaryKey: 'new_primary_key') + client.create_index!('uid', primaryKey: 'primary_key') + + task = client.index('uid').update(primaryKey: 'new_primary_key') + expect(task['type']).to eq('indexUpdate') + client.wait_for_task(task['uid']) + + index = client.fetch_index('uid') expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('uid') expect(index.primary_key).to eq('new_primary_key') @@ -70,32 +87,33 @@ expect(index.updated_at).to be_within(60).of(Time.now) end - it 'returns error if trying to update primary-key if it is already defined' do + it 'returns a failing task if primary-key is already defined' do index = client.index('uid') - update = index.add_documents({ id: 1, title: 'My Title' }) - index.wait_for_pending_update(update['updateId']) - expect do - index.update(primaryKey: 'new_primary_key') - end.to raise_meilisearch_api_error_with( - 400, - 'index_primary_key_already_exists', - 'invalid_request' - ) + index.add_documents!({ id: 1, title: 'My Title' }) + + task = index.update(primaryKey: 'new_primary_key') + expect(task['type']).to eq('indexUpdate') + achieved_task = client.wait_for_task(task['uid']) + + expect(achieved_task['status']).to eq('failed') + expect(achieved_task['error']['code']).to eq('index_primary_key_already_exists') end it 'supports options' do options = { timeout: 2, max_retries: 1 } new_client = MeiliSearch::Client.new(URL, MASTER_KEY, options) - index = new_client.create_index('options') + new_client.create_index!('options') + index = new_client.fetch_index('options') expect(index.options).to eq({ headers: { 'Content-Type' => 'application/json', - 'X-Meili-API-Key' => MASTER_KEY + 'Authorization' => "Bearer #{MASTER_KEY}" }, max_retries: 1, timeout: 2, convert_body?: true }) + expect(MeiliSearch::Index).to receive(:get).with( "#{URL}/indexes/options", { @@ -112,24 +130,31 @@ end it 'deletes index' do - index = client.create_index('uid') - expect(index.delete).to be_nil - expect { index.fetch_info }.to raise_index_not_found_meilisearch_api_error + client.create_index!('uid') + + task = client.index('uid').delete + expect(task['type']).to eq('indexDeletion') + achieved_task = client.wait_for_task(task['uid']) + expect(achieved_task['status']).to eq('succeeded') + expect { client.fetch_index('uid') }.to raise_index_not_found_meilisearch_api_error end it 'fails to manipulate index object after deletion' do - index = client.create_index('uid') - expect(index.delete).to be_nil + client.create_index!('uid') + + task = client.index('uid').delete + expect(task['type']).to eq('indexDeletion') + client.wait_for_task(task['uid']) + index = client.index('uid') expect { index.fetch_primary_key }.to raise_index_not_found_meilisearch_api_error expect { index.fetch_info }.to raise_index_not_found_meilisearch_api_error - expect { index.update(primaryKey: 'new_primary_key') }.to raise_index_not_found_meilisearch_api_error - expect { index.delete }.to raise_index_not_found_meilisearch_api_error end it 'works with method aliases' do - index = client.create_index('uid', primaryKey: 'primary_key') + client.create_index!('uid', primaryKey: 'primary_key') + index = client.fetch_index('uid') expect(index.method(:fetch_primary_key) == index.method(:get_primary_key)).to be_truthy expect(index.method(:update) == index.method(:update_index)).to be_truthy expect(index.method(:delete) == index.method(:delete_index)).to be_truthy @@ -137,9 +162,13 @@ context 'with snake_case options' do it 'does the request with camelCase attributes' do - index = client.create_index('uid') - index.update(primary_key: 'new_primary_key') + client.create_index!('uid') + + task = client.index('uid').update(primary_key: 'new_primary_key') + expect(task['type']).to eq('indexUpdate') + client.wait_for_task(task['uid']) + index = client.fetch_index('uid') expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('uid') expect(index.primary_key).to eq('new_primary_key') diff --git a/spec/meilisearch/index/documents_spec.rb b/spec/meilisearch/index/documents_spec.rb index 18804535..db9a9a2a 100644 --- a/spec/meilisearch/index/documents_spec.rb +++ b/spec/meilisearch/index/documents_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe 'MeiliSearch::Index - Documents' do - let(:index) { client.create_index(random_uid) } + let(:index) { client.index(random_uid) } context 'All basic tests with primary-key inference' do let(:documents) do @@ -18,10 +18,11 @@ describe 'adding documents' do it 'adds documents (as a array of documents)' do - response = index.add_documents(documents) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.add_documents(documents) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task['type']).to eq('documentsAddition') + client.wait_for_task(task['uid']) expect(index.documents.count).to eq(documents.count) end @@ -30,8 +31,8 @@ { object_id: 123, my_title: 'Pride and Prejudice', 'my-comment': 'A great book' } ] - response = index.add_documents(docs) - index.wait_for_pending_update(response['updateId']) + task = index.add_documents(docs) + client.wait_for_task(task['uid']) expect(index.documents.first.keys).to eq(docs.first.keys.map(&:to_s)) end @@ -49,8 +50,8 @@ response = index.add_documents_json(documents, 'objectRef') expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + expect(response).to have_key('uid') + index.wait_for_task(response['uid']) expect(index.documents.count).to eq(5) end @@ -63,8 +64,8 @@ NDJSON response = index.add_documents_ndjson(documents, 'objectRef') expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + expect(response).to have_key('uid') + index.wait_for_task(response['uid']) expect(index.documents.count).to eq(4) end @@ -77,49 +78,49 @@ CSV response = index.add_documents_csv(documents, 'objectRef') expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + expect(response).to have_key('uid') + index.wait_for_task(response['uid']) expect(index.documents.count).to eq(3) end it 'adds documents in a batch (as a array of documents)' do - response = index.add_documents_in_batches(documents, 5) - expect(response).to be_a(Array) - expect(response.count).to eq(2) # 2 batches, since we start with 5 < documents.count <= 10 documents - expect(response[0]).to have_key('updateId') - response.each do |response_object| - index.wait_for_pending_update(response_object['updateId']) + task = index.add_documents_in_batches(documents, 5) + expect(task).to be_a(Array) + expect(task.count).to eq(2) # 2 batches, since we start with 5 < documents.count <= 10 documents + expect(task[0]).to have_key('uid') + task.each do |task_object| + client.wait_for_task(task_object['uid']) end expect(index.documents.count).to eq(documents.count) end it 'adds documents synchronously (as an array of documents)' do - response = index.add_documents!(documents) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - expect(response).to have_key('status') - expect(response['status']).not_to eql('enqueued') - expect(response['status']).to eql('processed') + task = index.add_documents!(documents) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task).to have_key('status') + expect(task['status']).not_to eql('enqueued') + expect(task['status']).to eql('succeeded') expect(index.documents.count).to eq(documents.count) end it 'adds document batches synchronously (as an array of documents)' do - response = index.add_documents_in_batches!(documents, 5) - expect(response).to be_a(Array) - expect(response.count).to eq(2) # 2 batches, since we start with 5 < documents.count <= 10 documents - response.each do |response_object| - expect(response_object).to have_key('updateId') - expect(response_object).to have_key('status') - expect(response_object['status']).not_to eql('enqueued') - expect(response_object['status']).to eql('processed') + task = index.add_documents_in_batches!(documents, 5) + expect(task).to be_a(Array) + expect(task.count).to eq(2) # 2 batches, since we start with 5 < documents.count <= 10 documents + task.each do |task_object| + expect(task_object).to have_key('uid') + expect(task_object).to have_key('status') + expect(task_object['status']).not_to eql('enqueued') + expect(task_object['status']).to eql('succeeded') end expect(index.documents.count).to eq(documents.count) end it 'infers order of fields' do index.add_documents!(documents) - response = index.document(1) - expect(response.keys).to eq(['objectId', 'title', 'comment']) + task = index.document(1) + expect(task.keys).to eq(['objectId', 'title', 'comment']) end it 'infers primary-key attribute' do @@ -129,50 +130,52 @@ it 'create the index during document addition' do new_index = client.index('newIndex') - response = new_index.add_documents(documents) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - new_index.wait_for_pending_update(response['updateId']) + task = new_index.add_documents(documents) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + new_index.wait_for_task(task['uid']) expect(client.index('newIndex').fetch_primary_key).to eq('objectId') expect(client.index('newIndex').documents.count).to eq(documents.count) end it 'adds only one document to index (as an hash of one document)' do new_doc = { objectId: 30, title: 'Hamlet' } + client.create_index!('newIndex') + new_index = client.index('newIndex') expect do - response = index.add_documents(new_doc) - index.wait_for_pending_update(response['updateId']) - - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - expect(index.document(30)['title']).to eq('Hamlet') - end.to(change { index.documents.length }.by(1)) + task = new_index.add_documents!(new_doc) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(new_index.document(30)['title']).to eq('Hamlet') + end.to(change { new_index.documents.length }.by(1)) end it 'adds only one document synchronously to index (as an hash of one document)' do new_doc = { objectId: 30, title: 'Hamlet' } + client.create_index!('newIndex') + new_index = client.index('newIndex') expect do - response = index.add_documents!(new_doc) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - expect(response).to have_key('status') - expect(response['status']).to eq('processed') - expect(index.document(30)['title']).to eq('Hamlet') - end.to(change { index.documents.length }.by(1)) + task = new_index.add_documents!(new_doc) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task).to have_key('status') + expect(task['status']).to eq('succeeded') + expect(new_index.document(30)['title']).to eq('Hamlet') + end.to(change { new_index.documents.length }.by(1)) end it 'fails to add document with bad primary-key format' do index.add_documents!(documents) - response = index.add_documents(objectId: 'toto et titi', title: 'Unknown') - index.wait_for_pending_update(response['updateId']) - expect(index.get_update_status(response['updateId'])['status']).to eq('failed') + task = index.add_documents(objectId: 'toto et titi', title: 'Unknown') + client.wait_for_task(task['uid']) + expect(index.task(task['uid'])['status']).to eq('failed') end it 'fails to add document with no primary-key' do index.add_documents!(documents) - response = index.add_documents(id: 0, title: 'Unknown') - index.wait_for_pending_update(response['updateId']) - expect(index.get_update_status(response['updateId'])['status']).to eq('failed') + task = index.add_documents(id: 0, title: 'Unknown') + client.wait_for_task(task['uid']) + expect(index.task(task['uid'])['status']).to eq('failed') end end @@ -180,25 +183,25 @@ before { index.add_documents!(documents) } it 'gets one document from its primary-key' do - response = index.document(123) - expect(response).to be_a(Hash) - expect(response['title']).to eq('Pride and Prejudice') - expect(response['comment']).to eq('A great book') + task = index.document(123) + expect(task).to be_a(Hash) + expect(task['title']).to eq('Pride and Prejudice') + expect(task['comment']).to eq('A great book') end it 'browses documents' do - response = index.documents - expect(response).to be_a(Array) - expect(response.size).to eq(documents.count) + task = index.documents + expect(task).to be_a(Array) + expect(task.size).to eq(documents.count) expected_titles = documents.map { |doc| doc[:title] } - expect(response.map { |doc| doc['title'] }).to contain_exactly(*expected_titles) + expect(task.map { |doc| doc['title'] }).to contain_exactly(*expected_titles) end it 'browses documents with query parameters' do - response = index.documents(offset: 2, limit: 5) - expect(response).to be_a(Array) - expect(response.size).to eq(5) - expect(response.first['objectId']).to eq(index.documents[2]['objectId']) + task = index.documents(offset: 2, limit: 5) + expect(task).to be_a(Array) + expect(task.size).to eq(5) + expect(task.first['objectId']).to eq(index.documents[2]['objectId']) end end @@ -212,10 +215,10 @@ { objectId: id1, title: 'Sense and Sensibility' }, { objectId: id2, title: 'The Little Prince' } ] - response = index.update_documents(updated_documents) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_documents(updated_documents) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) doc1 = index.document(id1) doc2 = index.document(id2) expect(index.documents.count).to eq(documents.count) @@ -232,12 +235,12 @@ { objectId: id1, title: 'Sense and Sensibility' }, { objectId: id2, title: 'The Little Prince' } ] - response = index.update_documents!(updated_documents) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - expect(response).to have_key('status') - expect(response['status']).not_to eql('enqueued') - expect(response['status']).to eql('processed') + task = index.update_documents!(updated_documents) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task).to have_key('status') + expect(task['status']).not_to eql('enqueued') + expect(task['status']).to eql('succeeded') doc1 = index.document(id1) doc2 = index.document(id2) expect(index.documents.count).to eq(documents.count) @@ -254,14 +257,14 @@ { objectId: id1, title: 'Sense and Sensibility' }, { objectId: id2, title: 'The Little Prince' } ] - response = index.update_documents_in_batches!(updated_documents, 1) - expect(response).to be_a(Array) - expect(response.count).to eq(2) # 2 batches, since we have two items with batch size 1 - response.each do |response_object| - expect(response_object).to have_key('updateId') - expect(response_object).to have_key('status') - expect(response_object['status']).not_to eql('enqueued') - expect(response_object['status']).to eql('processed') + task = index.update_documents_in_batches!(updated_documents, 1) + expect(task).to be_a(Array) + expect(task.count).to eq(2) # 2 batches, since we have two items with batch size 1 + task.each do |task_object| + expect(task_object).to have_key('uid') + expect(task_object).to have_key('status') + expect(task_object['status']).not_to eql('enqueued') + expect(task_object['status']).to eql('succeeded') end doc1 = index.document(id1) doc2 = index.document(id2) @@ -275,10 +278,10 @@ it 'updates one document in index (as an hash of one document)' do id = 123 updated_document = { objectId: id, title: 'Emma' } - response = index.update_documents(updated_document) - index.wait_for_pending_update(response['updateId']) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') + task = index.update_documents(updated_document) + client.wait_for_task(task['uid']) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') expect(index.documents.count).to eq(documents.count) new_doc = index.document(id) expect(new_doc['title']).to eq(updated_document[:title]) @@ -288,12 +291,12 @@ it 'updates one document synchronously in index (as an hash of one document)' do id = 123 updated_document = { objectId: id, title: 'Emma' } - response = index.update_documents!(updated_document) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - expect(response).to have_key('status') - expect(response['status']).not_to eql('enqueued') - expect(response['status']).to eql('processed') + task = index.update_documents!(updated_document) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task).to have_key('status') + expect(task['status']).not_to eql('enqueued') + expect(task['status']).to eql('succeeded') expect(index.documents.count).to eq(documents.count) new_doc = index.document(id) expect(new_doc['title']).to eq(updated_document[:title]) @@ -303,10 +306,10 @@ it 'update a document with new fields' do id = 2 doc = { objectId: id, note: '8/10' } - response = index.update_documents(doc) - index.wait_for_pending_update(response['updateId']) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') + task = index.update_documents(doc) + client.wait_for_task(task['uid']) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') expect(index.documents.count).to eq(documents.count) new_document = index.document(id) expect(new_document['title']).to eq(documents.detect { |d| d[:objectId] == id }[:title]) @@ -316,10 +319,10 @@ it 'replaces document' do id = 123 new_title = 'Pride & Prejudice' - response = index.replace_documents(objectId: id, title: 'Pride & Prejudice', note: '8.5/10') - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.replace_documents(objectId: id, title: 'Pride & Prejudice', note: '8.5/10') + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) expect(index.documents.count).to eq(documents.count) doc = index.document(id) expect(doc['title']).to eq(new_title) @@ -333,22 +336,22 @@ it 'deletes one document from index' do id = 456 - response = index.delete_document(id) - index.wait_for_pending_update(response['updateId']) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') + task = index.delete_document(id) + client.wait_for_task(task['uid']) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') expect(index.documents.size).to eq(documents.count - 1) expect { index.document(id) }.to raise_document_not_found_meilisearch_api_error end it 'deletes one document synchronously from index' do id = 456 - response = index.delete_document!(id) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - expect(response).to have_key('status') - expect(response['status']).not_to eql('enqueued') - expect(response['status']).to eql('processed') + task = index.delete_document!(id) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task).to have_key('status') + expect(task['status']).not_to eql('enqueued') + expect(task['status']).to eql('succeeded') expect(index.documents.size).to eq(documents.count - 1) expect { index.document(id) }.to raise_document_not_found_meilisearch_api_error end @@ -357,20 +360,20 @@ id = 111 expect { index.document(id) }.to raise_document_not_found_meilisearch_api_error expect do - response = index.delete_document(id) - index.wait_for_pending_update(response['updateId']) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') + task = index.delete_document(id) + client.wait_for_task(task['uid']) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') end.not_to(change { index.documents.size }) end it 'deletes one document from index (with delete-batch route)' do id = 2 expect do - response = index.delete_documents(id) - index.wait_for_pending_update(response['updateId']) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') + task = index.delete_documents(id) + client.wait_for_task(task['uid']) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') end.to(change { index.documents.size }.by(-1)) expect { index.document(id) }.to raise_document_not_found_meilisearch_api_error end @@ -378,12 +381,12 @@ it 'deletes one document synchronously from index (with delete-batch route)' do id = 2 expect do - response = index.delete_documents!(id) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - expect(response).to have_key('status') - expect(response['status']).not_to eql('enqueued') - expect(response['status']).to eql('processed') + task = index.delete_documents!(id) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task).to have_key('status') + expect(task['status']).not_to eql('enqueued') + expect(task['status']).to eql('succeeded') end.to(change { index.documents.size }.by(-1)) expect { index.document(id) }.to raise_document_not_found_meilisearch_api_error end @@ -391,10 +394,10 @@ it 'deletes one document from index (with delete-batch route as an array of one uid)' do id = 123 expect do - response = index.delete_documents([id]) - index.wait_for_pending_update(response['updateId']) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') + task = index.delete_documents([id]) + client.wait_for_task(task['uid']) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') end.to(change { index.documents.size }.by(-1)) expect { index.document(id) }.to raise_document_not_found_meilisearch_api_error end @@ -402,12 +405,12 @@ it 'deletes one document synchronously from index (with delete-batch route as an array of one uid)' do id = 123 expect do - response = index.delete_documents!([id]) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - expect(response).to have_key('status') - expect(response['status']).not_to eql('enqueued') - expect(response['status']).to eql('processed') + task = index.delete_documents!([id]) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task).to have_key('status') + expect(task['status']).not_to eql('enqueued') + expect(task['status']).to eql('succeeded') end.to(change { index.documents.size }.by(-1)) expect { index.document(id) }.to raise_document_not_found_meilisearch_api_error end @@ -415,42 +418,42 @@ it 'deletes multiples documents from index' do docs_to_delete = [1, 4] expect do - response = index.delete_documents(docs_to_delete) - index.wait_for_pending_update(response['updateId']) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') + task = index.delete_documents(docs_to_delete) + client.wait_for_task(task['uid']) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') end.to(change { index.documents.size }.by(-2)) end it 'deletes multiples documents synchronously from index' do docs_to_delete = [1, 4] expect do - response = index.delete_documents!(docs_to_delete) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - expect(response).to have_key('status') - expect(response['status']).not_to eql('enqueued') - expect(response['status']).to eql('processed') + task = index.delete_documents!(docs_to_delete) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task).to have_key('status') + expect(task['status']).not_to eql('enqueued') + expect(task['status']).to eql('succeeded') end.to(change { index.documents.size }.by(-2)) end it 'clears all documents from index' do expect do - response = index.delete_all_documents - index.wait_for_pending_update(response['updateId']) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') + task = index.delete_all_documents + client.wait_for_task(task['uid']) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') expect(index.documents).to be_empty end.to(change { index.documents.size }.from(documents.size).to(0)) end it 'clears all documents synchronously from index' do - response = index.delete_all_documents! - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - expect(response).to have_key('status') - expect(response['status']).not_to eql('enqueued') - expect(response['status']).to eql('processed') + task = index.delete_all_documents! + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task).to have_key('status') + expect(task['status']).not_to eql('enqueued') + expect(task['status']).to eql('succeeded') expect(index.documents).to be_empty expect(index.documents.size).to eq(0) end @@ -478,23 +481,23 @@ end it 'adds documents and the primary-key' do - response = index.add_documents(documents, 'unique') - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.add_documents(documents, 'unique') + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) expect(index.fetch_primary_key).to eq('unique') end it 'does not take into account the new primary key' do index.add_documents!(documents, 'unique') - response = index.update_documents({ - unique: 3, - id: 1, - title: 'The Red and the Black' - }, 'id') - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_documents({ + unique: 3, + id: 1, + title: 'The Red and the Black' + }, 'id') + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) expect(index.fetch_primary_key).to eq('unique') doc = index.document(3) expect(doc['unique']).to eq(3) @@ -509,12 +512,12 @@ end it 'does not add the primary key and the documents either' do - response = index.update_documents(documents, 'objectId') - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_documents(documents, 'objectId') + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) expect(index.fetch_primary_key).to be_nil - expect(index.get_update_status(response['updateId'])['status']).to eq('failed') + expect(index.task(task['uid'])['status']).to eq('failed') end end @@ -524,12 +527,12 @@ end it 'does not add the primary key and the documents either' do - response = index.add_documents(documents, 'title') - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.add_documents(documents, 'title') + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) expect(index.fetch_primary_key).to be_nil - expect(index.get_update_status(response['updateId'])['status']).to eq('failed') + expect(index.task(task['uid'])['status']).to eq('failed') expect(index.documents.count).to eq(0) end end @@ -540,8 +543,8 @@ end it 'Impossible to push docs if the pk is missing' do - response = index.add_documents!(documents) - update = index.get_update_status(response['updateId']) + task = index.add_documents!(documents) + update = index.task(task['uid']) expect(update['status']).to eq('failed') expect(update['error']['code']).to eq('primary_key_inference_failed') end @@ -553,10 +556,10 @@ end it 'adds the documents anyway' do - response = index.add_documents(documents, 'unique') - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.add_documents(documents, 'unique') + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) expect(index.fetch_primary_key).to eq('unique') expect(index.documents.count).to eq(1) end diff --git a/spec/meilisearch/index/search/attributes_to_crop_spec.rb b/spec/meilisearch/index/search/attributes_to_crop_spec.rb index d6ba49ea..1cead71b 100644 --- a/spec/meilisearch/index/search/attributes_to_crop_spec.rb +++ b/spec/meilisearch/index/search/attributes_to_crop_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe 'MeiliSearch::Index - Cropped search' do - let(:index) { client.create_index('books') } + let(:index) { client.index('books') } let(:document) do { objectId: 42, @@ -10,10 +10,7 @@ } end - before do - response = index.add_documents(document) - index.wait_for_pending_update(response['updateId']) - end + before { index.add_documents!(document) } it 'does a custom search with attributes to crop' do response = index.search('galaxy', { attributesToCrop: ['description'], cropLength: 15 }) diff --git a/spec/meilisearch/index/search/facets_distribution_spec.rb b/spec/meilisearch/index/search/facets_distribution_spec.rb index ba811db4..657bf676 100644 --- a/spec/meilisearch/index/search/facets_distribution_spec.rb +++ b/spec/meilisearch/index/search/facets_distribution_spec.rb @@ -5,7 +5,7 @@ before do response = index.update_filterable_attributes(['genre', 'year', 'author']) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) end it 'does a custom search with facetsDistribution' do diff --git a/spec/meilisearch/index/search/filter_spec.rb b/spec/meilisearch/index/search/filter_spec.rb index 21724b18..0077a802 100644 --- a/spec/meilisearch/index/search/filter_spec.rb +++ b/spec/meilisearch/index/search/filter_spec.rb @@ -5,7 +5,7 @@ before do response = index.update_filterable_attributes(['genre', 'year', 'author']) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) end it 'does a custom search with one filter' do diff --git a/spec/meilisearch/index/search/multi_params_spec.rb b/spec/meilisearch/index/search/multi_params_spec.rb index 3cb78243..87b7306a 100644 --- a/spec/meilisearch/index/search/multi_params_spec.rb +++ b/spec/meilisearch/index/search/multi_params_spec.rb @@ -5,7 +5,7 @@ before do response = index.update_filterable_attributes(['genre']) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) end it 'does a custom search with attributes to crop, filter and attributes to highlight' do @@ -46,7 +46,7 @@ it 'does a custom search with filter, attributesToRetrieve and attributesToHighlight' do response = index.update_filterable_attributes(['genre']) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) response = index.search('prinec', { filter: ['genre = fantasy'], @@ -64,7 +64,7 @@ it 'does a custom search with facetsDistribution and limit' do response = index.update_filterable_attributes(['genre']) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) response = index.search('prinec', facetsDistribution: ['genre'], limit: 1) expect(response.keys).to contain_exactly( *DEFAULT_SEARCH_RESPONSE_KEYS, diff --git a/spec/meilisearch/index/search/offset_spec.rb b/spec/meilisearch/index/search/offset_spec.rb index ba6092a3..7cad424a 100644 --- a/spec/meilisearch/index/search/offset_spec.rb +++ b/spec/meilisearch/index/search/offset_spec.rb @@ -17,7 +17,7 @@ it 'does a placeholder search with an offset set to 3 and custom ranking rules' do response = index.update_ranking_rules(['objectId:asc']) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) response = index.search('') response_with_offset = index.search('', offset: 3) expect(response['hits'].first['objectId']).to eq(1) diff --git a/spec/meilisearch/index/search/q_spec.rb b/spec/meilisearch/index/search/q_spec.rb index ee663efc..062dcf1a 100644 --- a/spec/meilisearch/index/search/q_spec.rb +++ b/spec/meilisearch/index/search/q_spec.rb @@ -36,7 +36,7 @@ 'exactness', 'objectId:asc' ]) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) response = index.search('') expect(response['nbHits']).to eq(documents.count) expect(response['hits'].first['objectId']).to eq(1) diff --git a/spec/meilisearch/index/search/sort_spec.rb b/spec/meilisearch/index/search/sort_spec.rb index 7a203ed4..69ab33ee 100644 --- a/spec/meilisearch/index/search/sort_spec.rb +++ b/spec/meilisearch/index/search/sort_spec.rb @@ -4,7 +4,7 @@ include_context 'search books with author, genre, year' before do response = index.update_sortable_attributes(['year', 'author']) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) response = index.update_ranking_rules([ 'sort', @@ -14,7 +14,7 @@ 'attribute', 'exactness' ]) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) end it 'does a custom search with one sort' do diff --git a/spec/meilisearch/index/settings_spec.rb b/spec/meilisearch/index/settings_spec.rb index e337ee33..76094952 100644 --- a/spec/meilisearch/index/settings_spec.rb +++ b/spec/meilisearch/index/settings_spec.rb @@ -30,29 +30,30 @@ context 'On global settings routes' do let(:index) { client.index(uid) } - before { client.create_index(uid) } + before { client.create_index!(uid) } it 'gets default values of settings' do - response = index.settings - expect(response).to be_a(Hash) - expect(response.keys).to contain_exactly(*settings_keys) - expect(response['rankingRules']).to eq(default_ranking_rules) - expect(response['distinctAttribute']).to be_nil - expect(response['searchableAttributes']).to eq(default_searchable_attributes) - expect(response['displayedAttributes']).to eq(default_displayed_attributes) - expect(response['stopWords']).to eq([]) - expect(response['synonyms']).to eq({}) - expect(response['filterableAttributes']).to eq([]) - expect(response['sortableAttributes']).to eq([]) + settings = index.settings + expect(settings).to be_a(Hash) + expect(settings.keys).to contain_exactly(*settings_keys) + expect(settings['rankingRules']).to eq(default_ranking_rules) + expect(settings['distinctAttribute']).to be_nil + expect(settings['searchableAttributes']).to eq(default_searchable_attributes) + expect(settings['displayedAttributes']).to eq(default_displayed_attributes) + expect(settings['stopWords']).to eq([]) + expect(settings['synonyms']).to eq({}) + expect(settings['filterableAttributes']).to eq([]) + expect(settings['sortableAttributes']).to eq([]) end it 'updates multiples settings at the same time' do - response = index.update_settings( + task = index.update_settings( rankingRules: ['title:asc', 'typo'], distinctAttribute: 'title' ) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) settings = index.settings expect(settings['rankingRules']).to eq(['title:asc', 'typo']) expect(settings['distinctAttribute']).to eq('title') @@ -60,9 +61,10 @@ end it 'updates one setting without reset the others' do - response = index.update_settings(stopWords: ['the']) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_settings(stopWords: ['the']) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) settings = index.settings expect(settings['rankingRules']).to eq(default_ranking_rules) expect(settings['distinctAttribute']).to be_nil @@ -71,17 +73,18 @@ end it 'resets all settings' do - response = index.update_settings( + task = index.update_settings( rankingRules: ['title:asc', 'typo'], distinctAttribute: 'title', stopWords: ['the', 'a'], synonyms: { wow: ['world of warcraft'] } ) - index.wait_for_pending_update(response['updateId']) + client.wait_for_task(task['uid']) - response = index.reset_settings - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.reset_settings + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) settings = index.settings expect(settings['rankingRules']).to eq(default_ranking_rules) @@ -92,13 +95,13 @@ context 'with snake_case options' do it 'does the request with camelCase attributes' do - response = index.update_settings( + task = index.update_settings( ranking_rules: ['typo'], distinct_ATTribute: 'title', stopWords: ['a'] ) - index.wait_for_pending_update(response['updateId']) + client.wait_for_task(task['uid']) settings = index.settings expect(settings['rankingRules']).to eq(['typo']) @@ -113,48 +116,52 @@ let(:ranking_rules) { ['title:asc', 'words', 'typo'] } let(:wrong_ranking_rules) { ['title:asc', 'typos'] } - before { client.create_index(uid) } + before { client.create_index!(uid) } it 'gets default values of ranking rules' do - response = index.ranking_rules - expect(response).to eq(default_ranking_rules) + settings = index.ranking_rules + expect(settings).to eq(default_ranking_rules) end it 'updates ranking rules' do - response = index.update_ranking_rules(ranking_rules) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_ranking_rules(ranking_rules) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.ranking_rules).to eq(ranking_rules) end it 'updates ranking rules at null' do - response = index.update_ranking_rules(ranking_rules) - index.wait_for_pending_update(response['updateId']) + task = index.update_ranking_rules(ranking_rules) + client.wait_for_task(task['uid']) - response = index.update_ranking_rules(nil) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_ranking_rules(nil) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.ranking_rules).to eq(default_ranking_rules) end it 'fails when updating with wrong ranking rules name' do - response = index.update_ranking_rules(wrong_ranking_rules) - index.wait_for_pending_update(response['updateId']) + task = index.update_ranking_rules(wrong_ranking_rules) + client.wait_for_task(task['uid']) - response = index.get_update_status(response['updateId']) + task = index.task(task['uid']) - expect(response.keys).to include('error') - expect(response['error']['code']).to eq('invalid_ranking_rule') + expect(task['type']).to eq('settingsUpdate') + expect(task.keys).to include('error') + expect(task['error']['code']).to eq('invalid_ranking_rule') end it 'resets ranking rules' do - response = index.update_ranking_rules(ranking_rules) - index.wait_for_pending_update(response['updateId']) + task = index.update_ranking_rules(ranking_rules) + client.wait_for_task(task['uid']) - response = index.reset_ranking_rules - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.reset_ranking_rules + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.ranking_rules).to eq(default_ranking_rules) end @@ -165,36 +172,41 @@ let(:distinct_attribute) { 'title' } it 'gets default values of distinct attribute' do - client.create_index(uid) - response = index.distinct_attribute + client.create_index!(uid) + settings = index.distinct_attribute - expect(response).to be_nil + expect(settings).to be_nil end it 'updates distinct attribute' do - response = index.update_distinct_attribute(distinct_attribute) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_distinct_attribute(distinct_attribute) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.distinct_attribute).to eq(distinct_attribute) end it 'updates distinct attribute at null' do - response = index.update_distinct_attribute(distinct_attribute) - index.wait_for_pending_update(response['updateId']) + task = index.update_distinct_attribute(distinct_attribute) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.update_distinct_attribute(nil) - index.wait_for_pending_update(response['updateId']) + task = index.update_distinct_attribute(nil) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.distinct_attribute).to be_nil end it 'resets distinct attribute' do - response = index.update_distinct_attribute(distinct_attribute) - index.wait_for_pending_update(response['updateId']) + task = index.update_distinct_attribute(distinct_attribute) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.reset_distinct_attribute - index.wait_for_pending_update(response['updateId']) + task = index.reset_distinct_attribute + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.distinct_attribute).to be_nil end @@ -204,40 +216,45 @@ let(:index) { client.index(uid) } let(:searchable_attributes) { ['title', 'description'] } - before { client.create_index(uid) } + before { client.create_index!(uid) } it 'gets default values of searchable attributes' do - response = index.searchable_attributes - expect(response).to eq(default_searchable_attributes) + settings = index.searchable_attributes + expect(settings).to eq(default_searchable_attributes) end it 'updates searchable attributes' do - response = index.update_searchable_attributes(searchable_attributes) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_searchable_attributes(searchable_attributes) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.searchable_attributes).to eq(searchable_attributes) end it 'updates searchable attributes at null' do - response = index.update_searchable_attributes(searchable_attributes) - index.wait_for_pending_update(response['updateId']) + task = index.update_searchable_attributes(searchable_attributes) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.update_searchable_attributes(nil) - expect(response).to have_key('updateId') + task = index.update_searchable_attributes(nil) + expect(task['type']).to eq('settingsUpdate') + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) - index.wait_for_pending_update(response['updateId']) expect(index.searchable_attributes).to eq(default_searchable_attributes) end it 'resets searchable attributes' do - response = index.update_searchable_attributes(searchable_attributes) - index.wait_for_pending_update(response['updateId']) + task = index.update_searchable_attributes(searchable_attributes) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.reset_searchable_attributes - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.reset_searchable_attributes + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - expect(index.get_update_status(response['updateId'])['status']).to eq('processed') + expect(index.task(task['uid'])['status']).to eq('succeeded') expect(index.searchable_attributes).to eq(default_searchable_attributes) end end @@ -246,41 +263,46 @@ let(:index) { client.index(uid) } let(:displayed_attributes) { ['title', 'description'] } - before { client.create_index(uid) } + before { client.create_index!(uid) } it 'gets default values of displayed attributes' do - response = index.displayed_attributes - expect(response).to eq(default_displayed_attributes) + settings = index.displayed_attributes + expect(settings).to eq(default_displayed_attributes) end it 'updates displayed attributes' do - response = index.update_displayed_attributes(displayed_attributes) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_displayed_attributes(displayed_attributes) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.displayed_attributes).to contain_exactly(*displayed_attributes) end it 'updates displayed attributes at null' do - response = index.update_displayed_attributes(displayed_attributes) - index.wait_for_pending_update(response['updateId']) + task = index.update_displayed_attributes(displayed_attributes) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.update_displayed_attributes(nil) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_displayed_attributes(nil) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.displayed_attributes).to eq(default_displayed_attributes) end it 'resets displayed attributes' do - response = index.update_displayed_attributes(displayed_attributes) - index.wait_for_pending_update(response['updateId']) + task = index.update_displayed_attributes(displayed_attributes) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.reset_displayed_attributes - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.reset_displayed_attributes + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - expect(index.get_update_status(response['updateId'])['status']).to eq('processed') + expect(index.task(task['uid'])['status']).to eq('succeeded') expect(index.displayed_attributes).to eq(default_displayed_attributes) end end @@ -295,29 +317,30 @@ } end - before { client.create_index(uid) } + before { client.create_index!(uid) } it 'gets an empty hash of synonyms by default' do - response = index.synonyms - expect(response).to be_a(Hash) - expect(response).to be_empty + settings = index.synonyms + expect(settings).to be_a(Hash) + expect(settings).to be_empty end - it 'returns an updateId when updating' do - response = index.update_synonyms(synonyms) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + it 'returns an uid when updating' do + task = index.update_synonyms(synonyms) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) end it 'gets all the synonyms' do update_synonyms(index, synonyms) - response = index.synonyms - expect(response).to be_a(Hash) - expect(response.count).to eq(3) - expect(response.keys).to contain_exactly('wow', 'wolverine', 'logan') - expect(response['wow']).to be_a(Array) - expect(response['wow']).to eq(['world of warcraft']) + settings = index.synonyms + expect(settings).to be_a(Hash) + expect(settings.count).to eq(3) + expect(settings.keys).to contain_exactly('wow', 'wolverine', 'logan') + expect(settings['wow']).to be_a(Array) + expect(settings['wow']).to eq(['world of warcraft']) end it 'overwrites all synonyms when updating' do @@ -343,11 +366,12 @@ update_synonyms(index, synonyms) expect do - response = index.reset_synonyms + task = index.reset_synonyms - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.synonyms).to be_a(Hash) end.to(change { index.synonyms.length }.from(3).to(0)) @@ -359,45 +383,50 @@ let(:stop_words_array) { ['the', 'of'] } let(:stop_words_string) { 'a' } - before { client.create_index(uid) } + before { client.create_index!(uid) } it 'gets an empty array when there is no stop-words' do - response = index.stop_words - expect(response).to be_a(Array) - expect(response).to be_empty + settings = index.stop_words + expect(settings).to be_a(Array) + expect(settings).to be_empty end it 'updates stop-words when the body is valid (as an array)' do - response = index.update_stop_words(stop_words_array) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') + task = index.update_stop_words(stop_words_array) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') end it 'gets list of stop-words' do - response = index.update_stop_words(stop_words_array) - index.wait_for_pending_update(response['updateId']) - response = index.stop_words - expect(response).to be_a(Array) - expect(response).to contain_exactly(*stop_words_array) + task = index.update_stop_words(stop_words_array) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) + settings = index.stop_words + expect(settings).to be_a(Array) + expect(settings).to contain_exactly(*stop_words_array) end it 'updates stop-words when the body is valid (as single string)' do - response = index.update_stop_words(stop_words_string) - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_stop_words(stop_words_string) + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) sw = index.stop_words expect(sw).to be_a(Array) expect(sw).to contain_exactly(stop_words_string) end it 'updates stop-words at null' do - response = index.update_stop_words(stop_words_string) - index.wait_for_pending_update(response['updateId']) + task = index.update_stop_words(stop_words_string) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.update_stop_words(nil) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_stop_words(nil) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.stop_words).to be_empty end @@ -409,13 +438,15 @@ end it 'resets stop-words' do - response = index.update_stop_words(stop_words_string) - index.wait_for_pending_update(response['updateId']) + task = index.update_stop_words(stop_words_string) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.reset_stop_words - expect(response).to be_a(Hash) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.reset_stop_words + expect(task).to be_a(Hash) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.stop_words).to be_a(Array) expect(index.stop_words).to be_empty @@ -426,41 +457,46 @@ let(:index) { client.index(uid) } let(:filterable_attributes) { ['title', 'description'] } - before { client.create_index(uid) } + before { client.create_index!(uid) } it 'gets default values of filterable attributes' do - response = index.filterable_attributes - expect(response).to be_a(Array) - expect(response).to be_empty + settings = index.filterable_attributes + expect(settings).to be_a(Array) + expect(settings).to be_empty end it 'updates filterable attributes' do - response = index.update_filterable_attributes(filterable_attributes) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_filterable_attributes(filterable_attributes) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.filterable_attributes).to contain_exactly(*filterable_attributes) end it 'updates filterable attributes at null' do - response = index.update_filterable_attributes(filterable_attributes) - expect(response).to have_key('updateId') + task = index.update_filterable_attributes(filterable_attributes) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') - response = index.update_filterable_attributes(nil) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_filterable_attributes(nil) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.filterable_attributes).to be_empty end it 'resets filterable attributes' do - response = index.update_filterable_attributes(filterable_attributes) - expect(response).to have_key('updateId') + task = index.update_filterable_attributes(filterable_attributes) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') - response = index.reset_filterable_attributes - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.reset_filterable_attributes + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - expect(index.get_update_status(response['updateId'])['status']).to eq('processed') + expect(index.task(task['uid'])['status']).to eq('succeeded') expect(index.filterable_attributes).to be_empty end end @@ -469,41 +505,46 @@ let(:index) { client.index(uid) } let(:sortable_attributes) { ['title', 'description'] } - before { client.create_index(uid) } + before { client.create_index!(uid) } it 'gets default values of sortable attributes' do - response = index.sortable_attributes - expect(response).to be_a(Array) - expect(response).to be_empty + settings = index.sortable_attributes + expect(settings).to be_a(Array) + expect(settings).to be_empty end it 'updates sortable attributes' do - response = index.update_sortable_attributes(sortable_attributes) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_sortable_attributes(sortable_attributes) + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) + expect(task['type']).to eq('settingsUpdate') expect(index.sortable_attributes).to contain_exactly(*sortable_attributes) end it 'updates sortable attributes at null' do - response = index.update_sortable_attributes(sortable_attributes) - index.wait_for_pending_update(response['updateId']) + task = index.update_sortable_attributes(sortable_attributes) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.update_sortable_attributes(nil) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_sortable_attributes(nil) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) expect(index.sortable_attributes).to be_empty end it 'resets sortable attributes' do - response = index.update_sortable_attributes(sortable_attributes) - index.wait_for_pending_update(response['updateId']) + task = index.update_sortable_attributes(sortable_attributes) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.reset_sortable_attributes - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.reset_sortable_attributes + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - expect(index.get_update_status(response['updateId'])['status']).to eq('processed') + expect(index.task(task['uid'])['status']).to eq('succeeded') expect(index.sortable_attributes).to be_empty end end @@ -511,27 +552,28 @@ context 'Index with primary-key' do let(:index) { client.index(uid) } - before { client.create_index(uid, primaryKey: 'id') } + before { client.create_index!(uid, primaryKey: 'id') } it 'gets the default values of settings' do - response = index.settings - expect(response).to be_a(Hash) - expect(response.keys).to contain_exactly(*settings_keys) - expect(response['rankingRules']).to eq(default_ranking_rules) - expect(response['distinctAttribute']).to be_nil - expect(response['searchableAttributes']).to eq(default_searchable_attributes) - expect(response['displayedAttributes']).to eq(default_displayed_attributes) - expect(response['stopWords']).to eq([]) - expect(response['synonyms']).to eq({}) + settings = index.settings + expect(settings).to be_a(Hash) + expect(settings.keys).to contain_exactly(*settings_keys) + expect(settings['rankingRules']).to eq(default_ranking_rules) + expect(settings['distinctAttribute']).to be_nil + expect(settings['searchableAttributes']).to eq(default_searchable_attributes) + expect(settings['displayedAttributes']).to eq(default_displayed_attributes) + expect(settings['stopWords']).to eq([]) + expect(settings['synonyms']).to eq({}) end it 'updates multiples settings at the same time' do - response = index.update_settings( + task = index.update_settings( rankingRules: ['title:asc', 'typo'], distinctAttribute: 'title' ) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) settings = index.settings expect(settings['rankingRules']).to eq(['title:asc', 'typo']) expect(settings['distinctAttribute']).to eq('title') @@ -539,9 +581,10 @@ end it 'updates one setting without reset the others' do - response = index.update_settings(stopWords: ['the']) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.update_settings(stopWords: ['the']) + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) settings = index.settings expect(settings['rankingRules']).to eq(default_ranking_rules) expect(settings['distinctAttribute']).to be_nil @@ -550,7 +593,7 @@ end it 'resets all settings' do - response = index.update_settings( + task = index.update_settings( rankingRules: ['title:asc', 'typo'], distinctAttribute: 'title', stopWords: ['the'], @@ -558,11 +601,13 @@ wow: ['world of warcraft'] } ) - index.wait_for_pending_update(response['updateId']) + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) - response = index.reset_settings - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.reset_settings + expect(task).to have_key('uid') + expect(task['type']).to eq('settingsUpdate') + client.wait_for_task(task['uid']) settings = index.settings expect(settings['rankingRules']).to eq(default_ranking_rules) @@ -576,36 +621,36 @@ let(:index) { client.index(random_uid) } it 'does not add document when there is no primary-key' do - response = index.add_documents(title: 'Test') - index.wait_for_pending_update(response['updateId']) - response = index.get_update_status(response['updateId']) - expect(response.keys).to include('error') - expect(response['error']['code']).to eq('primary_key_inference_failed') + task = index.add_documents(title: 'Test') + client.wait_for_task(task['uid']) + task = index.task(task['uid']) + expect(task.keys).to include('error') + expect(task['error']['code']).to eq('primary_key_inference_failed') end it 'adds documents when there is a primary-key' do - response = index.add_documents(objectId: 1, title: 'Test') - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) + task = index.add_documents(objectId: 1, title: 'Test') + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) expect(index.documents.count).to eq(1) end it 'resets searchable/displayed attributes' do - response = index.update_displayed_attributes(['title', 'description']) - index.wait_for_pending_update(response['updateId']) - response = index.update_searchable_attributes(['title']) - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) - - response = index.reset_displayed_attributes - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) - expect(index.get_update_status(response['updateId'])['status']).to eq('processed') - - response = index.reset_searchable_attributes - expect(response).to have_key('updateId') - index.wait_for_pending_update(response['updateId']) - expect(index.get_update_status(response['updateId'])['status']).to eq('processed') + task = index.update_displayed_attributes(['title', 'description']) + client.wait_for_task(task['uid']) + task = index.update_searchable_attributes(['title']) + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) + + task = index.reset_displayed_attributes + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) + expect(index.task(task['uid'])['status']).to eq('succeeded') + + task = index.reset_searchable_attributes + expect(task).to have_key('uid') + client.wait_for_task(task['uid']) + expect(index.task(task['uid'])['status']).to eq('succeeded') expect(index.displayed_attributes).to eq(['*']) expect(index.searchable_attributes).to eq(['*']) @@ -615,7 +660,7 @@ context 'Aliases' do let(:index) { client.index(uid) } - before { client.create_index(uid) } + before { client.create_index!(uid) } it 'works with method aliases' do expect(index.method(:settings) == index.method(:get_settings)).to be_truthy @@ -630,8 +675,8 @@ end def update_synonyms(index, synonyms) - response = index.update_synonyms(synonyms) + task = index.update_synonyms(synonyms) - index.wait_for_pending_update(response['updateId']) + client.wait_for_task(task['uid']) end end diff --git a/spec/meilisearch/index/updates_spec.rb b/spec/meilisearch/index/updates_spec.rb deleted file mode 100644 index 1109e00a..00000000 --- a/spec/meilisearch/index/updates_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe 'MeiliSearch::Index - Updates' do - include_context 'search books with genre' - - it 'gets an empty array when nothing happened before' do - index = client.create_index('new_index') - response = index.get_all_update_status - expect(response).to be_a(Array) - expect(response).to be_empty - end - - it 'gets update status after adding documents' do - response = index.add_documents(documents) - update_id = response['updateId'] - index.wait_for_pending_update(update_id) - response = index.get_update_status(update_id) - expect(response).to be_a(Hash) - expect(response['updateId']).to eq(update_id) - expect(response['status']).to eq('processed') - expect(response['type']).to be_a(Hash) - end - - it 'gets all the update status' do - response = index.get_all_update_status - expect(response).to be_a(Array) - expect(response.count).to eq(1) - end - - it 'achieved_upate? method returns true' do - boolean = index.achieved_upate?(index.get_update_status(0)) - expect(boolean).to be_truthy - end - - it 'waits for pending update with default values' do - response = index.add_documents(documents) - update_id = response['updateId'] - status = index.wait_for_pending_update(update_id) - expect(status).to be_a(Hash) - expect(status['status']).not_to eq('enqueued') - end - - it 'waits for pending update with default values after several updates' do - index.add_documents(documents) - index.add_documents(documents) - index.add_documents(documents) - index.add_documents(documents) - index.add_documents(documents) - response = index.add_documents(documents) - update_id = response['updateId'] - status = index.wait_for_pending_update(update_id) - expect(status).to be_a(Hash) - expect(status['status']).not_to eq('enqueued') - end - - it 'waits for pending update with custom timeout_in_ms and raises MeiliSearchTimeoutError' do - index.add_documents(documents) - response = index.add_documents(documents) - update_id = response['updateId'] - expect do - index.wait_for_pending_update(update_id, 1) - end.to raise_error(MeiliSearch::TimeoutError) - end - - it 'waits for pending update with custom interval_in_ms and raises Timeout::Error' do - index.add_documents(documents) - response = index.add_documents(documents) - update_id = response['updateId'] - expect do - Timeout.timeout(0.1) do - index.wait_for_pending_update(update_id, 5000, 200) - end - end.to raise_error(Timeout::Error) - end -end diff --git a/spec/support/books_contexts.rb b/spec/support/books_contexts.rb index 3567254c..ae4dd326 100644 --- a/spec/support/books_contexts.rb +++ b/spec/support/books_contexts.rb @@ -16,7 +16,7 @@ before do response = index.add_documents(documents) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) end end @@ -91,6 +91,6 @@ before do response = index.add_documents(documents) - index.wait_for_pending_update(response['updateId']) + index.wait_for_task(response['uid']) end end From f52addcdbb160a6626532d3c80b8c19af72acea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar?= Date: Tue, 21 Dec 2021 15:33:18 +0100 Subject: [PATCH 04/14] Update tests according to the typo fix on MeiliSearch side --- spec/meilisearch/index/documents_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/meilisearch/index/documents_spec.rb b/spec/meilisearch/index/documents_spec.rb index db9a9a2a..1a62c977 100644 --- a/spec/meilisearch/index/documents_spec.rb +++ b/spec/meilisearch/index/documents_spec.rb @@ -21,7 +21,7 @@ task = index.add_documents(documents) expect(task).to be_a(Hash) expect(task).to have_key('uid') - expect(task['type']).to eq('documentsAddition') + expect(task['type']).to eq('documentAddition') client.wait_for_task(task['uid']) expect(index.documents.count).to eq(documents.count) end From e6acfa1b2544d9cea2f6c9bcc23f89d6fb3f05e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Tue, 21 Dec 2021 15:45:00 +0100 Subject: [PATCH 05/14] Remove get_or_create_index method (#277) --- lib/meilisearch/client.rb | 11 --------- spec/meilisearch/client/indexes_spec.rb | 32 ------------------------- 2 files changed, 43 deletions(-) diff --git a/lib/meilisearch/client.rb b/lib/meilisearch/client.rb index 26ceb7bf..9eac7bc2 100644 --- a/lib/meilisearch/client.rb +++ b/lib/meilisearch/client.rb @@ -32,17 +32,6 @@ def create_index!(index_uid, options = {}) wait_for_task(task['uid']) end - # def get_or_create_index(index_uid, options = {}) - # begin - # index_instance = fetch_index(index_uid) - # rescue ApiError => e - # raise e unless e.code == 'index_not_found' - - # index_instance = create_index(index_uid, options) - # end - # index_instance - # end - def delete_index(index_uid) index_object(index_uid).delete end diff --git a/spec/meilisearch/client/indexes_spec.rb b/spec/meilisearch/client/indexes_spec.rb index 2b6f5bfd..32653bc6 100644 --- a/spec/meilisearch/client/indexes_spec.rb +++ b/spec/meilisearch/client/indexes_spec.rb @@ -105,38 +105,6 @@ end end - # describe '#get_or_create_index' do - # it 'creates a new index' do - # expect do - # new_index = client.get_or_create_index('new_index') - - # expect(new_index).to be_a(MeiliSearch::Index) - # end.to change { client.indexes.length }.by(1) - - # found_index = client.fetch_index('new_index') - # expect(found_index.uid).to eq('new_index') - # expect(found_index.primary_key).to be_nil - # end - - # it 'gets an index that already exists' do - # client.create_index('existing_index') - - # expect do - # client.get_or_create_index('existing_index') - # end.not_to(change { client.indexes.length }) - # end - - # context 'when a primary key is provided' do - # it 'creates a new index' do - # expect do - # index = client.get_or_create_index('new_index', primaryKey: 'primary_key') - - # expect(index).to be_a(MeiliSearch::Index) - # end.to change { client.indexes.length }.by(1) - # end - # end - # end - describe '#indexes' do it 'returns MeiliSearch::Index objects' do client.create_index!('index') From d0f7fc9cdf16a4c650d0a8d6fff3e88edf64bd93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Tue, 21 Dec 2021 15:52:03 +0100 Subject: [PATCH 06/14] Remove delete_index_if_exists method (#278) --- lib/meilisearch/client.rb | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lib/meilisearch/client.rb b/lib/meilisearch/client.rb index 9eac7bc2..438fa83b 100644 --- a/lib/meilisearch/client.rb +++ b/lib/meilisearch/client.rb @@ -36,17 +36,6 @@ def delete_index(index_uid) index_object(index_uid).delete end - # # Usage: - # # client.delete_index_if_exists('indexUID') - # def delete_index_if_exists(index_uid) - # index_object(index_uid).delete - # true - # rescue ApiError => e - # raise e if e.code != 'index_not_found' - - # false - # end - # Usage: # client.index('indexUID') def index(index_uid) From 1519c96d4a0071a83f1bfc66e2b118a048eaf043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Tue, 21 Dec 2021 18:29:50 +0100 Subject: [PATCH 07/14] Add API keys methods (#279) * Add API keys methods * Fix linter errors --- lib/meilisearch/client.rb | 21 +++- lib/meilisearch/http_request.rb | 19 ++- spec/meilisearch/client/keys_spec.rb | 176 ++++++++++++++++++++------- 3 files changed, 165 insertions(+), 51 deletions(-) diff --git a/lib/meilisearch/client.rb b/lib/meilisearch/client.rb index 438fa83b..42c20180 100644 --- a/lib/meilisearch/client.rb +++ b/lib/meilisearch/client.rb @@ -55,7 +55,26 @@ def fetch_raw_index(index_uid) def keys http_get '/keys' end - alias get_keys keys + + def key(key_uid) + http_get "/keys/#{key_uid}" + end + + def create_key(key_options) + body = Utils.transform_attributes(key_options) + + http_post '/keys', body + end + + def update_key(key_uid, key_options) + body = Utils.transform_attributes(key_options) + + http_patch "/keys/#{key_uid}", body + end + + def delete_key(key_uid) + http_delete "/keys/#{key_uid}" + end ### HEALTH diff --git a/lib/meilisearch/http_request.rb b/lib/meilisearch/http_request.rb index 125ab5a3..45cf1320 100644 --- a/lib/meilisearch/http_request.rb +++ b/lib/meilisearch/http_request.rb @@ -49,6 +49,16 @@ def http_put(relative_path = '', body = nil, query_params = nil) ) end + def http_patch(relative_path = '', body = nil, query_params = nil) + send_request( + proc { |path, config| self.class.patch(path, config) }, + relative_path, + query_params: query_params, + body: body, + options: @options + ) + end + def http_delete(relative_path = '') send_request( proc { |path, config| self.class.delete(path, config) }, @@ -60,10 +70,11 @@ def http_delete(relative_path = '') private def build_default_options_headers(api_key = nil) - { - 'Content-Type' => 'application/json', - 'Authorization' => "Bearer #{api_key}" - }.compact + header = { + 'Content-Type' => 'application/json' + } + header = header.merge('Authorization' => "Bearer #{api_key}") unless api_key.nil? + header end def merge_options(default_options, added_options = {}) diff --git a/spec/meilisearch/client/keys_spec.rb b/spec/meilisearch/client/keys_spec.rb index e9b04453..f0c3931d 100644 --- a/spec/meilisearch/client/keys_spec.rb +++ b/spec/meilisearch/client/keys_spec.rb @@ -1,59 +1,143 @@ # frozen_string_literal: true RSpec.describe 'MeiliSearch::Client - Keys' do - it 'gets the list of keys' do - response = client.keys - expect(response).to be_a(Hash) - expect(response.count).to eq(2) - expect(response.keys).to contain_exactly('private', 'public') - expect(response['private']).to be_a(String) - expect(response['public']).to be_a(String) - end + context 'Test the default key roles' do + let(:public_key) { client.keys.filter { |k| k['description'].start_with? 'Default Search API Key' }.first } + let(:private_key) { client.keys.filter { |k| k['description'].start_with? 'Default Admin API Key' }.first } - it 'fails to get settings if public key used' do - public_key = client.keys['public'] - new_client = MeiliSearch::Client.new(URL, public_key) - expect do - new_client.index(random_uid).settings - end.to raise_meilisearch_api_error_with(403, 'invalid_api_key', 'auth') - end + it 'fails to get settings if public key used' do + new_client = MeiliSearch::Client.new(URL, public_key['key']) + expect do + new_client.index(random_uid).settings + end.to raise_meilisearch_api_error_with(403, 'invalid_api_key', 'auth') + end - it 'fails to get keys if private key used' do - private_key = client.keys['private'] - new_client = MeiliSearch::Client.new(URL, private_key) - expect do - new_client.keys - end.to raise_meilisearch_api_error_with(403, 'invalid_api_key', 'auth') - end + it 'fails to get keys if private key used' do + new_client = MeiliSearch::Client.new(URL, private_key['key']) + expect do + new_client.keys + end.to raise_meilisearch_api_error_with(403, 'invalid_api_key', 'auth') + end - it 'fails to search if no key used' do - new_client = MeiliSearch::Client.new(URL) - expect do - new_client.index(random_uid).settings - end.to raise_meilisearch_api_error_with(401, 'missing_authorization_header', 'auth') - end + it 'fails to search if no key used' do + new_client = MeiliSearch::Client.new(URL) + expect do + new_client.index(random_uid).settings + end.to raise_meilisearch_api_error_with(401, 'missing_authorization_header', 'auth') + end - it 'succeeds to search when using public key' do - uid = random_uid - public_key = client.keys['public'] - index = client.index(uid) - index.add_documents!(title: 'Test') + it 'succeeds to search when using public key' do + uid = random_uid + index = client.index(uid) + index.add_documents!(title: 'Test') - new_client = MeiliSearch::Client.new(URL, public_key) - response = new_client.index(uid).search('test') - expect(response).to have_key('hits') - end + new_client = MeiliSearch::Client.new(URL, public_key['key']) + response = new_client.index(uid).search('test') + expect(response).to have_key('hits') + end - it 'succeeds to get settings when using private key' do - uid = random_uid - client.create_index!(uid) - private_key = client.keys['private'] - new_client = MeiliSearch::Client.new(URL, private_key) - response = new_client.index(uid).settings - expect(response).to have_key('rankingRules') + it 'succeeds to get settings when using private key' do + uid = random_uid + client.create_index!(uid) + new_client = MeiliSearch::Client.new(URL, private_key['key']) + response = new_client.index(uid).settings + expect(response).to have_key('rankingRules') + end end - it 'works with method aliases' do - expect(client.method(:keys) == client.method(:get_keys)).to be_truthy + context 'Test the key managements' do + it 'gets the list of the default keys' do + response = client.keys + expect(response).to be_a(Array) + expect(response.count).to be >= 2 + end + + it 'creates a key' do + key_options = { + description: 'A new key to add docs', + actions: ['documents.add'], + indexes: ['*'], + expiresAt: nil + } + new_key = client.create_key(key_options) + expect(new_key['expiresAt']).to be_nil + expect(new_key['key']).to be_a(String) + expect(new_key['createdAt']).to be_a(String) + expect(new_key['updatedAt']).to be_a(String) + expect(new_key['indexes']).to eq(['*']) + expect(new_key['description']).to eq('A new key to add docs') + end + + it 'creates a key using snake_case' do + key_options = { + description: 'A new key to add docs', + actions: ['documents.add'], + indexes: ['*'], + expires_at: nil + } + new_key = client.create_key(key_options) + expect(new_key['expiresAt']).to be_nil + expect(new_key['key']).to be_a(String) + expect(new_key['createdAt']).to be_a(String) + expect(new_key['updatedAt']).to be_a(String) + expect(new_key['indexes']).to eq(['*']) + expect(new_key['description']).to eq('A new key to add docs') + end + + it 'gets a key' do + key_options = { + description: 'A new key to delete docs', + actions: ['documents.delete'], + indexes: ['*'], + expiresAt: nil + } + new_key = client.create_key(key_options) + expect(client.key(new_key['key'])['description']).to eq('A new key to delete docs') + end + + it 'update a key' do + key_options = { + description: 'A new key to delete docs', + actions: ['documents.delete'], + indexes: ['*'], + expiresAt: nil + } + new_key = client.create_key(key_options) + + new_updated_key = client.update_key(new_key['key'], indexes: ['coco']) + + expect(new_updated_key['key']).to eq(new_key['key']) + expect(new_updated_key['description']).to eq(new_key['description']) + expect(new_updated_key['indexes']).to eq(['coco']) + end + + it 'update a key using snake_case' do + key_options = { + description: 'A new key to delete docs', + actions: ['documents.delete'], + indexes: ['*'], + expires_at: nil + } + new_key = client.create_key(key_options) + + new_updated_key = client.update_key(new_key['key'], indexes: ['coco']) + + expect(new_updated_key['key']).to eq(new_key['key']) + expect(new_updated_key['description']).to eq(new_key['description']) + expect(new_updated_key['indexes']).to eq(['coco']) + end + + it 'deletes a key' do + key_options = { + description: 'A new key to add docs', + actions: ['documents.add'], + indexes: ['*'], + expiresAt: nil + } + new_key = client.create_key(key_options) + + client.delete_key(new_key['key']) + expect(client.keys.filter { |k| k['key'] == new_key['key'] }).to be_empty + end end end From 014cda4c78ce36677737d90541553899dcca6255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Tue, 4 Jan 2022 18:52:09 +0100 Subject: [PATCH 08/14] Update spec according to the right behavior of /keys (#282) --- spec/meilisearch/client/keys_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/meilisearch/client/keys_spec.rb b/spec/meilisearch/client/keys_spec.rb index f0c3931d..cdea47a8 100644 --- a/spec/meilisearch/client/keys_spec.rb +++ b/spec/meilisearch/client/keys_spec.rb @@ -2,8 +2,8 @@ RSpec.describe 'MeiliSearch::Client - Keys' do context 'Test the default key roles' do - let(:public_key) { client.keys.filter { |k| k['description'].start_with? 'Default Search API Key' }.first } - let(:private_key) { client.keys.filter { |k| k['description'].start_with? 'Default Admin API Key' }.first } + let(:public_key) { client.keys['results'].filter { |k| k['description'].start_with? 'Default Search API Key' }.first } + let(:private_key) { client.keys['results'].filter { |k| k['description'].start_with? 'Default Admin API Key' }.first } it 'fails to get settings if public key used' do new_client = MeiliSearch::Client.new(URL, public_key['key']) @@ -47,9 +47,9 @@ context 'Test the key managements' do it 'gets the list of the default keys' do - response = client.keys - expect(response).to be_a(Array) - expect(response.count).to be >= 2 + results = client.keys['results'] + expect(results).to be_a(Array) + expect(results.count).to be >= 2 end it 'creates a key' do From 4bdf2d19041ed2809aff31d2196313c737ea311c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Tue, 11 Jan 2022 18:26:46 +0100 Subject: [PATCH 09/14] Add code samples for v0.25.0 (#286) * Add code samples for v0.25.0 * Update .code-samples.meilisearch.yaml --- .code-samples.meilisearch.yaml | 60 ++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 02f07f27..89d19597 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -43,10 +43,14 @@ delete_documents_1: |- client.index('movies').delete_documents([23488, 153738, 437035, 363869]) search_post_1: |- client.index('movies').search('american ninja') -get_update_1: |- +get_task_by_index_1: |- client.index('movies').task(1) -get_all_updates_1: |- +get_all_tasks_by_index_1: |- client.index('movies').tasks +get_task_1: |- + client.task(1) +get_all_tasks_1: |- + client.tasks get_keys_1: |- client.keys get_settings_1: |- @@ -400,3 +404,55 @@ geosearch_guide_sort_usage_1: |- client.index('restaurants').search('', { sort: ['_geoPoint(48.8583701,2.2922926):asc'] }) geosearch_guide_sort_usage_2: |- client.index('restaurants').search('', { sort: ['_geoPoint(48.8583701,2.2922926):asc', 'rating:desc'] }) +authorization_header_1: |- + client = MeiliSearch::Client.new('http://127.0.0.1:7700', 'masterKey') + cleint.keys +get_one_key_1: |- + client.key('d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4') +get_all_keys_1: |- + client.keys +create_a_key_1: |- + client.create_key( + description: 'Add documents: Products API key', + actions: ['documents.add'], + indexes: ['products'], + expires_at: '2042-04-02T00:42:42Z' + ) +update_a_key_1: |- + client.update_key( + 'd0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4', + { + description: 'Manage documents: Products/Reviews API key', + actions: [ + 'documents.add', + 'documents.delete' + ], + indexes: [ + 'products', + 'reviews' + ], + expires_at: '2042-04-02T00:42:42Z' + } + ) +delete_a_key_1: |- + client.delete_key('d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4') +security_guide_search_key_1: |- + client = MeiliSearch::Client.new('http://127.0.0.1:7700', 'apiKey') + client.index('patient_medical_records').search +security_guide_update_key_1: |- + client = MeiliSearch::Client.new('http://127.0.0.1:7700', 'masterKey') + client.update_key('d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4', indexes: ['doctors']) +security_guide_create_key_1: |- + client = MeiliSearch::Client.new('http://127.0.0.1:7700', 'masterKey') + client.create_key( + description: 'Search patient records key', + actions: ['search'], + indexes: ['patient_medical_records'], + expires_at: '2023-01-01T00:00:00Z' + ) +security_guide_list_keys_1: |- + client = MeiliSearch::Client.new('http://127.0.0.1:7700', 'masterKey') + cleint.keys +security_guide_delete_key_1: |- + client = MeiliSearch::Client.new('http://127.0.0.1:7700', 'masterKey') + client.delete_key('d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4') From 5c42479836dbe11504d4cec413fbf8b2ae4fdbfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Wed, 12 Jan 2022 11:47:31 +0100 Subject: [PATCH 10/14] Update README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amélie --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index be4ca717..ce3eeecf 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ documents = [ index.add_documents(documents) # => { "uid": 0 } ``` -With the `uid`, you can check the status (`enqueued`, `processing`, `succeeded` or `failed`) of your documents addition using the [update endpoint](https://docs.meilisearch.com/reference/api/updates.html#get-an-update-status). +With the `uid`, you can check the status (`enqueued`, `processing`, `succeeded` or `failed`) of your documents addition using the [task](https://docs.meilisearch.com/reference/api/tasks.html#get-task). 💡 To customize the `Client`, for example, increasing the default timeout, please check out [this section](https://github.com/meilisearch/meilisearch-ruby/wiki/Client-Options) of the Wiki. From b6c8d4ff62db4ee847fa6384d9e00a4d10892a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Wed, 12 Jan 2022 11:47:47 +0100 Subject: [PATCH 11/14] Update .code-samples.meilisearch.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amélie --- .code-samples.meilisearch.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 89d19597..7d57beb9 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -452,7 +452,7 @@ security_guide_create_key_1: |- ) security_guide_list_keys_1: |- client = MeiliSearch::Client.new('http://127.0.0.1:7700', 'masterKey') - cleint.keys + client.keys security_guide_delete_key_1: |- client = MeiliSearch::Client.new('http://127.0.0.1:7700', 'masterKey') client.delete_key('d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4') From d0f45fffefacd8426a70e60304716b9bdcc7f8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Wed, 12 Jan 2022 11:47:51 +0100 Subject: [PATCH 12/14] Update .code-samples.meilisearch.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amélie --- .code-samples.meilisearch.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 7d57beb9..d011cab0 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -406,7 +406,7 @@ geosearch_guide_sort_usage_2: |- client.index('restaurants').search('', { sort: ['_geoPoint(48.8583701,2.2922926):asc', 'rating:desc'] }) authorization_header_1: |- client = MeiliSearch::Client.new('http://127.0.0.1:7700', 'masterKey') - cleint.keys + client.keys get_one_key_1: |- client.key('d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4') get_all_keys_1: |- From 982dc5806009beeba093bfba4d49fb590a24c374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar=20-=20curqui?= Date: Wed, 12 Jan 2022 13:29:42 +0100 Subject: [PATCH 13/14] Apply changes after the review (#285) * Apply changes after the review * Fix linter errors --- lib/meilisearch/client.rb | 6 +- lib/meilisearch/index.rb | 3 +- lib/meilisearch/task.rb | 6 +- spec/meilisearch/client/indexes_spec.rb | 38 +++++--- spec/meilisearch/client/keys_spec.rb | 110 ++++++++++++------------ spec/meilisearch/client/tasks_spec.rb | 55 +++++------- 6 files changed, 108 insertions(+), 110 deletions(-) diff --git a/lib/meilisearch/client.rb b/lib/meilisearch/client.rb index 42c20180..569e834c 100644 --- a/lib/meilisearch/client.rb +++ b/lib/meilisearch/client.rb @@ -113,11 +113,11 @@ def dump_status(dump_uid) ### TASKS def tasks - task_endpoint.global_tasks + task_endpoint.task_list end def task(task_uid) - task_endpoint.global_task(task_uid) + task_endpoint.task(task_uid) end def wait_for_task(task_uid, timeout_in_ms = 5000, interval_in_ms = 50) @@ -131,7 +131,7 @@ def index_object(uid, primary_key = nil) end def task_endpoint - Task.new(@base_url, @api_key, @options) + @task_endpoint ||= Task.new(@base_url, @api_key, @options) end end end diff --git a/lib/meilisearch/index.rb b/lib/meilisearch/index.rb index ca9ecb7d..f3cc2091 100644 --- a/lib/meilisearch/index.rb +++ b/lib/meilisearch/index.rb @@ -7,7 +7,6 @@ class Index < HTTPRequest attr_reader :uid, :primary_key, :created_at, :updated_at def initialize(index_uid, url, api_key = nil, primary_key = nil, options = {}) - @url = url @uid = index_uid @primary_key = primary_key super(url, api_key, options) @@ -195,7 +194,7 @@ def search(query, options = {}) ### TASKS def task_endpoint - Task.new(@url, @api_key, @options) + @task_endpoint ||= Task.new(@base_url, @api_key, @options) end private :task_endpoint diff --git a/lib/meilisearch/task.rb b/lib/meilisearch/task.rb index 4d0af45a..00dec031 100644 --- a/lib/meilisearch/task.rb +++ b/lib/meilisearch/task.rb @@ -5,11 +5,11 @@ module MeiliSearch class Task < HTTPRequest - def global_tasks + def task_list http_get '/tasks/' end - def global_task(task_uid) + def task(task_uid) http_get "/tasks/#{task_uid}" end @@ -24,7 +24,7 @@ def index_task(index_uid, task_uid) def wait_for_task(task_uid, timeout_in_ms = 5000, interval_in_ms = 50) Timeout.timeout(timeout_in_ms.to_f / 1000) do loop do - task = global_task(task_uid) + task = task(task_uid) return task if achieved_task?(task) sleep interval_in_ms.to_f / 1000 diff --git a/spec/meilisearch/client/indexes_spec.rb b/spec/meilisearch/client/indexes_spec.rb index 32653bc6..55760a09 100644 --- a/spec/meilisearch/client/indexes_spec.rb +++ b/spec/meilisearch/client/indexes_spec.rb @@ -5,10 +5,12 @@ context 'without a primary key' do it 'creates an index' do task = client.create_index('new_index') + expect(task['type']).to eq('indexCreation') - client.wait_for_task(task['uid']) + client.wait_for_task(task['uid']) index = client.fetch_index('new_index') + expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('new_index') expect(index.primary_key).to be_nil @@ -16,10 +18,12 @@ it 'creates an index synchronously' do task = client.create_index!('new_index') + expect(task['type']).to eq('indexCreation') expect(task['status']).to eq('succeeded') index = client.fetch_index('new_index') + expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('new_index') expect(index.primary_key).to be_nil @@ -29,10 +33,12 @@ context 'with a primary key' do it 'creates an index' do task = client.create_index('new_index', primaryKey: 'primary_key') + expect(task['type']).to eq('indexCreation') - client.wait_for_task(task['uid']) + client.wait_for_task(task['uid']) index = client.fetch_index('new_index') + expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('new_index') expect(index.primary_key).to eq('primary_key') @@ -41,10 +47,12 @@ it 'creates an index synchronously' do task = client.create_index!('new_index', primaryKey: 'primary_key') + expect(task['type']).to eq('indexCreation') expect(task['status']).to eq('succeeded') index = client.fetch_index('new_index') + expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('new_index') expect(index.primary_key).to eq('primary_key') @@ -72,10 +80,12 @@ primaryKey: 'primary_key', uid: 'not_primary_key' ) + expect(task['type']).to eq('indexCreation') - client.wait_for_task(task['uid']) + client.wait_for_task(task['uid']) index = client.fetch_index('new_index') + expect(index).to be_a(MeiliSearch::Index) expect(index.uid).to eq('new_index') expect(index.primary_key).to eq('primary_key') @@ -86,13 +96,14 @@ context 'when an index with a given uid already exists' do it 'returns a failing task' do - task1 = client.create_index!('existing_index') - task2 = client.create_index!('existing_index') - expect(task1['type']).to eq('indexCreation') - expect(task2['type']).to eq('indexCreation') - expect(task1['status']).to eq('succeeded') - expect(task2['status']).to eq('failed') - expect(task2['error']['code']).to eq('index_already_exists') + initial_task = client.create_index!('existing_index') + last_task = client.create_index!('existing_index') + + expect(initial_task['type']).to eq('indexCreation') + expect(last_task['type']).to eq('indexCreation') + expect(initial_task['status']).to eq('succeeded') + expect(last_task['status']).to eq('failed') + expect(last_task['error']['code']).to eq('index_already_exists') end end @@ -108,7 +119,9 @@ describe '#indexes' do it 'returns MeiliSearch::Index objects' do client.create_index!('index') + index = client.indexes.first + expect(index).to be_a(MeiliSearch::Index) end @@ -162,7 +175,6 @@ describe '#fetch_raw_index' do it 'fetch a specific index raw Hash response based on uid' do client.create_index!('specific_index_fetch_raw', primaryKey: 'primary_key') - index = client.fetch_index('specific_index_fetch_raw') raw_response = index.fetch_raw_info @@ -179,7 +191,6 @@ describe '#index' do it 'returns an index object with the provided uid' do client.create_index!('existing_index', primaryKey: 'primary_key') - # this index is in memory, without metadata from server index = client.index('existing_index') @@ -197,9 +208,10 @@ context 'when the index exists' do it 'deletes the index' do client.create_index!('existing_index') - task = client.delete_index('existing_index') + expect(task['type']).to eq('indexDeletion') + achieved_task = client.wait_for_task(task['uid']) expect(achieved_task['status']).to eq('succeeded') diff --git a/spec/meilisearch/client/keys_spec.rb b/spec/meilisearch/client/keys_spec.rb index cdea47a8..dba8212d 100644 --- a/spec/meilisearch/client/keys_spec.rb +++ b/spec/meilisearch/client/keys_spec.rb @@ -1,26 +1,29 @@ # frozen_string_literal: true RSpec.describe 'MeiliSearch::Client - Keys' do - context 'Test the default key roles' do - let(:public_key) { client.keys['results'].filter { |k| k['description'].start_with? 'Default Search API Key' }.first } - let(:private_key) { client.keys['results'].filter { |k| k['description'].start_with? 'Default Admin API Key' }.first } + context 'When a client uses default key roles' do + let(:search_key) { client.keys['results'].find { |k| k['description'].start_with? 'Default Search' } } + let(:admin_key) { client.keys['results'].find { |k| k['description'].start_with? 'Default Admin' } } it 'fails to get settings if public key used' do - new_client = MeiliSearch::Client.new(URL, public_key['key']) + new_client = MeiliSearch::Client.new(URL, search_key['key']) + expect do new_client.index(random_uid).settings end.to raise_meilisearch_api_error_with(403, 'invalid_api_key', 'auth') end it 'fails to get keys if private key used' do - new_client = MeiliSearch::Client.new(URL, private_key['key']) + new_client = MeiliSearch::Client.new(URL, admin_key['key']) + expect do new_client.keys end.to raise_meilisearch_api_error_with(403, 'invalid_api_key', 'auth') end - it 'fails to search if no key used' do + it 'fails to get settings if no key is used' do new_client = MeiliSearch::Client.new(URL) + expect do new_client.index(random_uid).settings end.to raise_meilisearch_api_error_with(401, 'missing_authorization_header', 'auth') @@ -30,36 +33,50 @@ uid = random_uid index = client.index(uid) index.add_documents!(title: 'Test') - - new_client = MeiliSearch::Client.new(URL, public_key['key']) + new_client = MeiliSearch::Client.new(URL, search_key['key']) response = new_client.index(uid).search('test') + expect(response).to have_key('hits') end it 'succeeds to get settings when using private key' do uid = random_uid client.create_index!(uid) - new_client = MeiliSearch::Client.new(URL, private_key['key']) + new_client = MeiliSearch::Client.new(URL, admin_key['key']) response = new_client.index(uid).settings + expect(response).to have_key('rankingRules') end end - context 'Test the key managements' do + context 'When managing keys' do + let(:delete_docs_key_options) do + { + description: 'A new key to delete docs', + actions: ['documents.delete'], + indexes: ['*'], + expiresAt: nil + } + end + let(:add_docs_key_options) do + { + description: 'A new key to add docs', + actions: ['documents.add'], + indexes: ['*'], + expiresAt: nil + } + end + it 'gets the list of the default keys' do results = client.keys['results'] + expect(results).to be_a(Array) expect(results.count).to be >= 2 end it 'creates a key' do - key_options = { - description: 'A new key to add docs', - actions: ['documents.add'], - indexes: ['*'], - expiresAt: nil - } - new_key = client.create_key(key_options) + new_key = client.create_key(add_docs_key_options) + expect(new_key['expiresAt']).to be_nil expect(new_key['key']).to be_a(String) expect(new_key['createdAt']).to be_a(String) @@ -69,13 +86,8 @@ end it 'creates a key using snake_case' do - key_options = { - description: 'A new key to add docs', - actions: ['documents.add'], - indexes: ['*'], - expires_at: nil - } - new_key = client.create_key(key_options) + new_key = client.create_key(add_docs_key_options) + expect(new_key['expiresAt']).to be_nil expect(new_key['key']).to be_a(String) expect(new_key['createdAt']).to be_a(String) @@ -85,25 +97,22 @@ end it 'gets a key' do - key_options = { - description: 'A new key to delete docs', - actions: ['documents.delete'], - indexes: ['*'], - expiresAt: nil - } - new_key = client.create_key(key_options) + new_key = client.create_key(delete_docs_key_options) + expect(client.key(new_key['key'])['description']).to eq('A new key to delete docs') - end - it 'update a key' do - key_options = { - description: 'A new key to delete docs', - actions: ['documents.delete'], - indexes: ['*'], - expiresAt: nil - } - new_key = client.create_key(key_options) + key = client.key(new_key['key']) + expect(key['expiresAt']).to be_nil + expect(key['key']).to be_a(String) + expect(key['createdAt']).to be_a(String) + expect(key['updatedAt']).to be_a(String) + expect(key['indexes']).to eq(['*']) + expect(key['description']).to eq('A new key to delete docs') + end + + it 'updates a key' do + new_key = client.create_key(delete_docs_key_options) new_updated_key = client.update_key(new_key['key'], indexes: ['coco']) expect(new_updated_key['key']).to eq(new_key['key']) @@ -111,15 +120,8 @@ expect(new_updated_key['indexes']).to eq(['coco']) end - it 'update a key using snake_case' do - key_options = { - description: 'A new key to delete docs', - actions: ['documents.delete'], - indexes: ['*'], - expires_at: nil - } - new_key = client.create_key(key_options) - + it 'updates a key using snake_case' do + new_key = client.create_key(delete_docs_key_options) new_updated_key = client.update_key(new_key['key'], indexes: ['coco']) expect(new_updated_key['key']).to eq(new_key['key']) @@ -128,15 +130,9 @@ end it 'deletes a key' do - key_options = { - description: 'A new key to add docs', - actions: ['documents.add'], - indexes: ['*'], - expiresAt: nil - } - new_key = client.create_key(key_options) - + new_key = client.create_key(add_docs_key_options) client.delete_key(new_key['key']) + expect(client.keys.filter { |k| k['key'] == new_key['key'] }).to be_empty end end diff --git a/spec/meilisearch/client/tasks_spec.rb b/spec/meilisearch/client/tasks_spec.rb index 02dc955c..7c725e0b 100644 --- a/spec/meilisearch/client/tasks_spec.rb +++ b/spec/meilisearch/client/tasks_spec.rb @@ -3,46 +3,43 @@ RSpec.describe 'MeiliSearch::Tasks' do include_context 'search books with genre' - # Ensure there is at least 1 task - before do - task = index.add_documents!(documents) - @task_uid = task['uid'] - end + let(:enqueued_task_keys) { ['uid', 'indexUid', 'status', 'type', 'enqueuedAt'] } + let(:succeeded_task_keys) { [*enqueued_task_keys, 'details', 'duration', 'startedAt', 'finishedAt'] } + let!(:doc_addition_task) { index.add_documents!(documents) } + let(:task_uid) { doc_addition_task['uid'] } it 'gets a task of an index' do - task = index.task(@task_uid) - expect(task).to be_a(Hash) - expect(task['uid']).to eq(@task_uid) - expect(task).to have_key('status') - expect(task).to have_key('indexUid') - expect(task).to have_key('type') + task = index.task(task_uid) + + expect(task.keys).to include(*succeeded_task_keys) end it 'gets all the tasks of an index' do tasks = index.tasks + expect(tasks['results']).to be_a(Array) - expect(tasks['results'].first).to have_key('uid') - expect(tasks['results'].first).to have_key('status') - expect(tasks['results'].first).to have_key('indexUid') - expect(tasks['results'].first).to have_key('type') + + last_task = tasks['results'].first + + expect(last_task.keys).to include(*succeeded_task_keys) end it 'gets a task of the MeiliSearch instance' do task = client.task(0) + expect(task).to be_a(Hash) expect(task['uid']).to eq(0) - expect(task).to have_key('status') - expect(task).to have_key('indexUid') - expect(task).to have_key('type') + expect(task.keys).to include(*succeeded_task_keys) end it 'gets all the tasks of the MeiliSearch instance' do tasks = client.tasks + expect(tasks['results']).to be_a(Array) - expect(tasks['results'].first).to have_key('uid') - expect(tasks['results'].first).to have_key('status') - expect(tasks['results'].first).to have_key('indexUid') - expect(tasks['results'].first).to have_key('type') + + last_task = tasks['results'].first + + expect(last_task.keys).to include(*succeeded_task_keys) end describe '#index.wait_for_task' do @@ -55,13 +52,10 @@ end it 'waits for task with default values after several updates' do - index.add_documents(documents) - index.add_documents(documents) - index.add_documents(documents) - index.add_documents(documents) - index.add_documents(documents) + 5.times { index.add_documents(documents) } task = index.add_documents(documents) status = index.wait_for_task(task['uid']) + expect(status).to be_a(Hash) expect(status['status']).not_to eq('enqueued') end @@ -95,13 +89,10 @@ end it 'waits for task with default values after several updates' do - index.add_documents(documents) - index.add_documents(documents) - index.add_documents(documents) - index.add_documents(documents) - index.add_documents(documents) + 5.times { index.add_documents(documents) } task = index.add_documents(documents) status = client.wait_for_task(task['uid']) + expect(status).to be_a(Hash) expect(status['status']).not_to eq('enqueued') end From 175d2bfa0b76b9beed7cbd551539e04ee46f2135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9mentine=20Urquizar?= Date: Wed, 12 Jan 2022 13:52:34 +0100 Subject: [PATCH 14/14] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce3eeecf..6a5543a8 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ index.update_filterable_attributes([ You only need to perform this operation once. -Note that MeiliSearch will rebuild your index whenever you update `filterableAttributes`. Depending on the size of your dataset, this might take time. You can track the process using the [update status](https://docs.meilisearch.com/reference/api/updates.html#get-an-update-status). +Note that MeiliSearch will rebuild your index whenever you update `filterableAttributes`. Depending on the size of your dataset, this might take time. You can track the process using the [tasks](https://docs.meilisearch.com/reference/api/tasks.html#get-task)). Then, you can perform the search: