mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Merge pull request #23465 from opf/xwiki-search
Implement real search_pages for XWiki
This commit is contained in:
@@ -65,6 +65,10 @@ module Wikis
|
||||
Adapters::Registry["#{self.class.registry_prefix}.#{registry_path}"].new(model: self, **init_options)
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#<#{self.class.name} id: #{id} name: #{name}>"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_universal_identifier
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
module Wikis
|
||||
module Adapters
|
||||
module Providers
|
||||
module XWiki
|
||||
module Queries
|
||||
module Concerns
|
||||
module XWikiQuery
|
||||
ACCEPT_HEADERS = { "Accept" => "application/json" }.freeze
|
||||
|
||||
def authenticated(auth_strategy)
|
||||
Adapters::Authentication[auth_strategy].call do |http|
|
||||
yield http.with(headers: ACCEPT_HEADERS)
|
||||
end
|
||||
end
|
||||
|
||||
def rest_url(path, query: nil)
|
||||
# TODO: we might be able to extract a common URL formatting helper from Storages::UrlBuilder
|
||||
url = "#{provider.url.chomp('/')}/rest/#{path.delete_prefix('/')}"
|
||||
return url if query.nil?
|
||||
|
||||
"#{url}?#{query.to_query}"
|
||||
end
|
||||
|
||||
def handle_response(response)
|
||||
return failure(code: :connection_error) if response.is_a?(HTTPX::ErrorResponse)
|
||||
|
||||
case response
|
||||
in { status: 200..299 }
|
||||
begin
|
||||
json = response.json
|
||||
rescue MultiJson::ParseError
|
||||
return failure(code: :invalid_response)
|
||||
end
|
||||
|
||||
yield json
|
||||
in { status: 401 | 403 }
|
||||
failure(code: :unauthorized)
|
||||
in { status: 404 }
|
||||
failure(code: :not_found)
|
||||
else
|
||||
failure(code: :request_failed)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -34,51 +34,25 @@ module Wikis
|
||||
module XWiki
|
||||
module Queries
|
||||
class PageInfo < BaseQuery
|
||||
ACCEPT_HEADERS = { "Accept" => "application/json" }.freeze
|
||||
include Concerns::XWikiQuery
|
||||
|
||||
def call(input_data:, auth_strategy:)
|
||||
ref = PageReference.parse(input_data.identifier)
|
||||
return failure(code: :not_found) unless ref
|
||||
|
||||
url = "#{provider.url.chomp('/')}/rest#{ref.rest_path}"
|
||||
Adapters::Authentication[auth_strategy].call do |http|
|
||||
handle_response(
|
||||
http.with(headers: ACCEPT_HEADERS).get(url),
|
||||
identifier: input_data.identifier
|
||||
)
|
||||
authenticated(auth_strategy) do |http|
|
||||
handle_response(http.get(rest_url(ref.rest_path))) do |data|
|
||||
success(
|
||||
Results::PageInfo.new(
|
||||
identifier: input_data.identifier,
|
||||
title: data["title"],
|
||||
href: data["xwikiAbsoluteUrl"],
|
||||
provider:
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def handle_response(response, identifier:)
|
||||
return failure(code: :connection_error) if response.is_a?(HTTPX::ErrorResponse)
|
||||
|
||||
case response
|
||||
in { status: 200..299 }
|
||||
handle_success_response(response, identifier:)
|
||||
in { status: 401 | 403 }
|
||||
failure(code: :unauthorized)
|
||||
in { status: 404 }
|
||||
failure(code: :not_found)
|
||||
else
|
||||
failure(code: :request_failed)
|
||||
end
|
||||
end
|
||||
|
||||
def handle_success_response(response, identifier:)
|
||||
data = response.json
|
||||
success(
|
||||
Results::PageInfo.new(
|
||||
identifier:,
|
||||
title: data["title"],
|
||||
href: data["xwikiAbsoluteUrl"],
|
||||
provider:
|
||||
)
|
||||
)
|
||||
rescue MultiJson::ParseError
|
||||
failure(code: :invalid_response)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -34,16 +34,33 @@ module Wikis
|
||||
module XWiki
|
||||
module Queries
|
||||
class SearchPages < BaseQuery
|
||||
def call(input_data:, **)
|
||||
# TODO: use real API endpoints once available
|
||||
include Concerns::XWikiQuery
|
||||
|
||||
titles = [
|
||||
"#{input_data.query} makes XWiki special",
|
||||
"API documentation of #{input_data.query}",
|
||||
"A brief introduction on configuring your own #{input_data.query}."
|
||||
]
|
||||
MAXIMUM_RESULTS = 50
|
||||
|
||||
success(titles.map { Results::PageInfo.new(identifier: "1338", title: it, href: "#", provider:) })
|
||||
def call(input_data:, auth_strategy:)
|
||||
query = { q: "\"#{escape_quotes input_data.query}\"", number: MAXIMUM_RESULTS }
|
||||
|
||||
authenticated(auth_strategy) do |http|
|
||||
handle_response(http.get(rest_url("wikis/query", query:))) do |json|
|
||||
success(
|
||||
json.fetch("searchResults")
|
||||
.uniq { |r| r.fetch("id") }
|
||||
.map do |r|
|
||||
result = page_info(identifier: r.fetch("id"), auth_strategy:)
|
||||
return result if result.failure?
|
||||
|
||||
result.value!
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def escape_quotes(string)
|
||||
string.gsub("\\", "\\\\").gsub('"', '\"')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,9 +43,16 @@ FactoryBot.define do
|
||||
factory :xwiki_provider, class: "Wikis::XWikiProvider", parent: :wiki_provider do
|
||||
url { "https://xwiki.example.com/" }
|
||||
|
||||
transient do
|
||||
oauth_client_id { "openproject-#{SecureRandom.hex(8)}" }
|
||||
oauth_client_secret { SecureRandom.alphanumeric(20) }
|
||||
end
|
||||
|
||||
trait :with_oauth_client do
|
||||
after(:create) do |provider, _|
|
||||
create(:oauth_client, integration: provider)
|
||||
after(:create) do |provider, evaluator|
|
||||
create :oauth_client, integration: provider,
|
||||
client_id: evaluator.oauth_client_id,
|
||||
client_secret: evaluator.oauth_client_secret
|
||||
end
|
||||
end
|
||||
|
||||
@@ -65,6 +72,15 @@ FactoryBot.define do
|
||||
end
|
||||
end
|
||||
|
||||
trait :for_local_connection do
|
||||
with_connected_user
|
||||
|
||||
url { "https://xwiki.local" }
|
||||
connected_user_token { ENV.fetch("XWIKI_LOCAL_OAUTH_CLIENT_ACCESS_TOKEN", "TOKEN_NOT_CONFIGURED") }
|
||||
oauth_client_id { ENV.fetch("XWIKI_LOCAL_OAUTH_CLIENT_ID", "CLIENT_ID_NOT_CONFIGURED") }
|
||||
oauth_client_secret { ENV.fetch("XWIKI_LOCAL_OAUTH_CLIENT_SECRET", "CLIENT_SECRET_NOT_CONFIGURED") }
|
||||
end
|
||||
|
||||
trait :with_oauth_configured do
|
||||
after(:create) do |provider, _evaluator|
|
||||
create(:oauth_client, integration: provider)
|
||||
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Wikis::Adapters::Providers::XWiki::Queries::SearchPages, :webmock do
|
||||
subject { described_class.new(model: provider).call(input_data:, auth_strategy:) }
|
||||
|
||||
let(:provider) { create(:xwiki_provider, :for_local_connection, connected_user: user) }
|
||||
let(:input_data) { Wikis::Adapters::Input::SearchPages.build(query:).value! }
|
||||
let(:auth_strategy) { provider.auth_strategy_for(user).value! }
|
||||
|
||||
let(:user) { create(:user) }
|
||||
|
||||
# Before recording VCR cassettes of this, ensure pages with the following titles exist in XWiki:
|
||||
# * Test Page for RSpec
|
||||
# * "Quoted" pages can be tricky
|
||||
|
||||
context "when there are exactly matching pages", vcr: "xwiki/query_exact_match" do
|
||||
let(:query) { "Test Page for RSpec" }
|
||||
|
||||
it { is_expected.to be_success }
|
||||
|
||||
it "returns matching pages" do
|
||||
expect(subject.value!).not_to be_empty
|
||||
expect(subject.value!.first.title).to eq("Test Page for RSpec")
|
||||
end
|
||||
|
||||
it "returns no other random results" do
|
||||
expect(subject.value!.count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are partially matching pages", vcr: "xwiki/query_partial_match" do
|
||||
let(:query) { "for RSpec" }
|
||||
|
||||
it { is_expected.to be_success }
|
||||
|
||||
it "returns matching pages" do
|
||||
expect(subject.value!).not_to be_empty
|
||||
expect(subject.value!.first.title).to eq("Test Page for RSpec")
|
||||
end
|
||||
|
||||
it "returns no other random results" do
|
||||
expect(subject.value!.count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the searched page contains quotes", vcr: "xwiki/query_quoted_match" do
|
||||
let(:query) { '"Quoted" pages can be tricky' }
|
||||
|
||||
it { is_expected.to be_success }
|
||||
|
||||
it "returns matching pages" do
|
||||
expect(subject.value!).not_to be_empty
|
||||
expect(subject.value!.first.title).to eq('"Quoted" pages can be tricky')
|
||||
end
|
||||
|
||||
it "returns no other random results" do
|
||||
expect(subject.value!.count).to eq(1)
|
||||
end
|
||||
|
||||
context "and the query omits the quotes", vcr: "xwiki/query_unquoted_match" do
|
||||
let(:query) { "Quoted pages can be tricky" }
|
||||
|
||||
it { is_expected.to be_success }
|
||||
|
||||
it "returns matching pages" do
|
||||
expect(subject.value!).not_to be_empty
|
||||
expect(subject.value!.first.title).to eq('"Quoted" pages can be tricky')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are no matching pages", vcr: "xwiki/query_no_match" do
|
||||
let(:query) { "A page that does not exist" }
|
||||
|
||||
it { is_expected.to be_success }
|
||||
|
||||
it "returns an empty result" do
|
||||
expect(subject.value!).to eq([])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: get
|
||||
uri: https://xwiki.local/rest/wikis/query?number=50&q=%22Test%20Page%20for%20RSpec%22
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- OpenProject 17.6.0 HTTPX Client
|
||||
Accept:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer <SECRET>
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Language:
|
||||
- en
|
||||
Content-Script-Type:
|
||||
- text/javascript
|
||||
Content-Type:
|
||||
- application/json;charset=UTF-8
|
||||
Date:
|
||||
- Tue, 02 Jun 2026 08:17:22 GMT
|
||||
Set-Cookie:
|
||||
- JSESSIONID=A90934AE8F68AA76D0E0970863A314F8; Path=/; HttpOnly
|
||||
Xwiki-Form-Token:
|
||||
- 2XZUUfWArYhRgLYx4nHjhQ
|
||||
Xwiki-User:
|
||||
- xwiki:XWiki.admin
|
||||
Xwiki-Version:
|
||||
- 18.3.0
|
||||
Content-Length:
|
||||
- '790'
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"links":[],"searchResults":[{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null}],"type":"page","id":"xwiki:Test
|
||||
Page.WebHome","pageFullName":"Test Page.WebHome","title":"Test Page for RSpec","wiki":"xwiki","space":"Test
|
||||
Page","pageName":"WebHome","modified":1780386902000,"author":"xwiki:XWiki.admin","authorName":null,"version":"4.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":30.283539,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}'
|
||||
recorded_at: Tue, 02 Jun 2026 08:17:22 GMT
|
||||
- request:
|
||||
method: get
|
||||
uri: https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- OpenProject 17.6.0 HTTPX Client
|
||||
Accept:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer <SECRET>
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Language:
|
||||
- en
|
||||
Content-Script-Type:
|
||||
- text/javascript
|
||||
Content-Type:
|
||||
- application/json;charset=UTF-8
|
||||
Date:
|
||||
- Tue, 02 Jun 2026 08:17:22 GMT
|
||||
Set-Cookie:
|
||||
- JSESSIONID=6D38F35499AE562F0EEE91795F9951CF; Path=/; HttpOnly
|
||||
Xwiki-Form-Token:
|
||||
- 2XZUUfWArYhRgLYx4nHjhQ
|
||||
Xwiki-User:
|
||||
- xwiki:XWiki.admin
|
||||
Xwiki-Version:
|
||||
- 18.3.0
|
||||
Content-Length:
|
||||
- '2224'
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/Test%20Page.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"xwiki:Test
|
||||
Page.WebHome","fullName":"Test Page.WebHome","wiki":"xwiki","space":"Test
|
||||
Page","name":"WebHome","title":"Test Page for RSpec","rawTitle":"Test Page
|
||||
for RSpec","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"4.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/Test%20Page/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/Test%20Page/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":4,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780383689000,"creator":"XWiki.admin","creatorName":null,"modified":1780386902000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"","content":"This
|
||||
is a test page that I created with my own hands.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"Test
|
||||
Page","name":"Test Page","type":"space","url":"https://xwiki.local/bin/view/Test%20Page/"},{"label":"WebHome","name":"WebHome","type":"document","url":"https://xwiki.local/bin/view/Test%20Page/"}]},"rights":[],"renderedContent":null}'
|
||||
recorded_at: Tue, 02 Jun 2026 08:17:22 GMT
|
||||
recorded_with: VCR 6.4.0
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: get
|
||||
uri: https://xwiki.local/rest/wikis/query?number=50&q=%22A%20page%20that%20does%20not%20exist%22
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- OpenProject 17.6.0 HTTPX Client
|
||||
Accept:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer <SECRET>
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Language:
|
||||
- en
|
||||
Content-Script-Type:
|
||||
- text/javascript
|
||||
Content-Type:
|
||||
- application/json;charset=UTF-8
|
||||
Date:
|
||||
- Tue, 02 Jun 2026 08:17:23 GMT
|
||||
Set-Cookie:
|
||||
- JSESSIONID=9D417B4F0A9D4C117C903A54394DAD6C; Path=/; HttpOnly
|
||||
Xwiki-Form-Token:
|
||||
- 2XZUUfWArYhRgLYx4nHjhQ
|
||||
Xwiki-User:
|
||||
- xwiki:XWiki.admin
|
||||
Xwiki-Version:
|
||||
- 18.3.0
|
||||
Content-Length:
|
||||
- '251'
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"links":[],"searchResults":[],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}'
|
||||
recorded_at: Tue, 02 Jun 2026 08:17:23 GMT
|
||||
recorded_with: VCR 6.4.0
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: get
|
||||
uri: https://xwiki.local/rest/wikis/query?number=50&q=%22for%20RSpec%22
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- OpenProject 17.6.0 HTTPX Client
|
||||
Accept:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer <SECRET>
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Language:
|
||||
- en
|
||||
Content-Script-Type:
|
||||
- text/javascript
|
||||
Content-Type:
|
||||
- application/json;charset=UTF-8
|
||||
Date:
|
||||
- Tue, 02 Jun 2026 08:17:22 GMT
|
||||
Set-Cookie:
|
||||
- JSESSIONID=4570EBB986F92482503F494102024098; Path=/; HttpOnly
|
||||
Xwiki-Form-Token:
|
||||
- 2XZUUfWArYhRgLYx4nHjhQ
|
||||
Xwiki-User:
|
||||
- xwiki:XWiki.admin
|
||||
Xwiki-Version:
|
||||
- 18.3.0
|
||||
Content-Length:
|
||||
- '790'
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"links":[],"searchResults":[{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null}],"type":"page","id":"xwiki:Test
|
||||
Page.WebHome","pageFullName":"Test Page.WebHome","title":"Test Page for RSpec","wiki":"xwiki","space":"Test
|
||||
Page","pageName":"WebHome","modified":1780386902000,"author":"xwiki:XWiki.admin","authorName":null,"version":"4.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":14.608791,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}'
|
||||
recorded_at: Tue, 02 Jun 2026 08:17:22 GMT
|
||||
- request:
|
||||
method: get
|
||||
uri: https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- OpenProject 17.6.0 HTTPX Client
|
||||
Accept:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer <SECRET>
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Language:
|
||||
- en
|
||||
Content-Script-Type:
|
||||
- text/javascript
|
||||
Content-Type:
|
||||
- application/json;charset=UTF-8
|
||||
Date:
|
||||
- Tue, 02 Jun 2026 08:17:22 GMT
|
||||
Set-Cookie:
|
||||
- JSESSIONID=36828A84C85C858E144AA581B1A1F138; Path=/; HttpOnly
|
||||
Xwiki-Form-Token:
|
||||
- 2XZUUfWArYhRgLYx4nHjhQ
|
||||
Xwiki-User:
|
||||
- xwiki:XWiki.admin
|
||||
Xwiki-Version:
|
||||
- 18.3.0
|
||||
Content-Length:
|
||||
- '2224'
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/Test%20Page.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"xwiki:Test
|
||||
Page.WebHome","fullName":"Test Page.WebHome","wiki":"xwiki","space":"Test
|
||||
Page","name":"WebHome","title":"Test Page for RSpec","rawTitle":"Test Page
|
||||
for RSpec","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"4.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/Test%20Page/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/Test%20Page/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":4,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780383689000,"creator":"XWiki.admin","creatorName":null,"modified":1780386902000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"","content":"This
|
||||
is a test page that I created with my own hands.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"Test
|
||||
Page","name":"Test Page","type":"space","url":"https://xwiki.local/bin/view/Test%20Page/"},{"label":"WebHome","name":"WebHome","type":"document","url":"https://xwiki.local/bin/view/Test%20Page/"}]},"rights":[],"renderedContent":null}'
|
||||
recorded_at: Tue, 02 Jun 2026 08:17:22 GMT
|
||||
recorded_with: VCR 6.4.0
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: get
|
||||
uri: https://xwiki.local/rest/wikis/query?number=50&q=%22%5C%22Quoted%5C%22%20pages%20can%20be%20tricky%22
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- OpenProject 17.6.0 HTTPX Client
|
||||
Accept:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer <SECRET>
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Language:
|
||||
- en
|
||||
Content-Script-Type:
|
||||
- text/javascript
|
||||
Content-Type:
|
||||
- application/json;charset=UTF-8
|
||||
Date:
|
||||
- Tue, 02 Jun 2026 08:17:22 GMT
|
||||
Set-Cookie:
|
||||
- JSESSIONID=C28E0999BF663CA702569EE1C5C696E2; Path=/; HttpOnly
|
||||
Xwiki-Form-Token:
|
||||
- 2XZUUfWArYhRgLYx4nHjhQ
|
||||
Xwiki-User:
|
||||
- xwiki:XWiki.admin
|
||||
Xwiki-Version:
|
||||
- 18.3.0
|
||||
Content-Length:
|
||||
- '893'
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"links":[],"searchResults":[{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null}],"type":"page","id":"xwiki:\"Quoted\"
|
||||
pages can be tricky.WebHome","pageFullName":"\"Quoted\" pages can be tricky.WebHome","title":"\"Quoted\"
|
||||
pages can be tricky","wiki":"xwiki","space":"\"Quoted\" pages can be tricky","pageName":"WebHome","modified":1780387197000,"author":"xwiki:XWiki.admin","authorName":null,"version":"1.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":42.605682,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}'
|
||||
recorded_at: Tue, 02 Jun 2026 08:17:22 GMT
|
||||
- request:
|
||||
method: get
|
||||
uri: https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- OpenProject 17.6.0 HTTPX Client
|
||||
Accept:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer <SECRET>
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Language:
|
||||
- en
|
||||
Content-Script-Type:
|
||||
- text/javascript
|
||||
Content-Type:
|
||||
- application/json;charset=UTF-8
|
||||
Date:
|
||||
- Tue, 02 Jun 2026 08:17:22 GMT
|
||||
Set-Cookie:
|
||||
- JSESSIONID=EC142E0079C91196143B051273FDA2FD; Path=/; HttpOnly
|
||||
Xwiki-Form-Token:
|
||||
- 2XZUUfWArYhRgLYx4nHjhQ
|
||||
Xwiki-User:
|
||||
- xwiki:XWiki.admin
|
||||
Xwiki-Version:
|
||||
- 18.3.0
|
||||
Content-Length:
|
||||
- '2642'
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/%22Quoted%22%20pages%20can%20be%20tricky.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"xwiki:\"Quoted\"
|
||||
pages can be tricky.WebHome","fullName":"\"Quoted\" pages can be tricky.WebHome","wiki":"xwiki","space":"\"Quoted\"
|
||||
pages can be tricky","name":"WebHome","title":"\"Quoted\" pages can be tricky","rawTitle":"\"Quoted\"
|
||||
pages can be tricky","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"1.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":1,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780387197000,"creator":"XWiki.admin","creatorName":null,"modified":1780387197000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"","content":"When
|
||||
the page title contains quotes, it''s harder to exactly match their page title.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"\"Quoted\"
|
||||
pages can be tricky","name":"\"Quoted\" pages can be tricky","type":"space","url":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/"},{"label":"WebHome","name":"WebHome","type":"document","url":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/"}]},"rights":[],"renderedContent":null}'
|
||||
recorded_at: Tue, 02 Jun 2026 08:17:22 GMT
|
||||
recorded_with: VCR 6.4.0
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: get
|
||||
uri: https://xwiki.local/rest/wikis/query?number=50&q=%22Quoted%20pages%20can%20be%20tricky%22
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- OpenProject 17.6.0 HTTPX Client
|
||||
Accept:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer <SECRET>
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Language:
|
||||
- en
|
||||
Content-Script-Type:
|
||||
- text/javascript
|
||||
Content-Type:
|
||||
- application/json;charset=UTF-8
|
||||
Date:
|
||||
- Tue, 02 Jun 2026 08:17:23 GMT
|
||||
Set-Cookie:
|
||||
- JSESSIONID=10D557C0A4C7D3C599B80C2FA01F5FF5; Path=/; HttpOnly
|
||||
Xwiki-Form-Token:
|
||||
- 2XZUUfWArYhRgLYx4nHjhQ
|
||||
Xwiki-User:
|
||||
- xwiki:XWiki.admin
|
||||
Xwiki-Version:
|
||||
- 18.3.0
|
||||
Content-Length:
|
||||
- '893'
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"links":[],"searchResults":[{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null}],"type":"page","id":"xwiki:\"Quoted\"
|
||||
pages can be tricky.WebHome","pageFullName":"\"Quoted\" pages can be tricky.WebHome","title":"\"Quoted\"
|
||||
pages can be tricky","wiki":"xwiki","space":"\"Quoted\" pages can be tricky","pageName":"WebHome","modified":1780387197000,"author":"xwiki:XWiki.admin","authorName":null,"version":"1.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":42.605682,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}'
|
||||
recorded_at: Tue, 02 Jun 2026 08:17:23 GMT
|
||||
- request:
|
||||
method: get
|
||||
uri: https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome
|
||||
body:
|
||||
encoding: US-ASCII
|
||||
string: ''
|
||||
headers:
|
||||
User-Agent:
|
||||
- OpenProject 17.6.0 HTTPX Client
|
||||
Accept:
|
||||
- application/json
|
||||
Accept-Encoding:
|
||||
- gzip, deflate
|
||||
Authorization:
|
||||
- Bearer <SECRET>
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Content-Language:
|
||||
- en
|
||||
Content-Script-Type:
|
||||
- text/javascript
|
||||
Content-Type:
|
||||
- application/json;charset=UTF-8
|
||||
Date:
|
||||
- Tue, 02 Jun 2026 08:17:23 GMT
|
||||
Set-Cookie:
|
||||
- JSESSIONID=85112D2673FA7F3B99AEC6BF0A182372; Path=/; HttpOnly
|
||||
Xwiki-Form-Token:
|
||||
- 2XZUUfWArYhRgLYx4nHjhQ
|
||||
Xwiki-User:
|
||||
- xwiki:XWiki.admin
|
||||
Xwiki-Version:
|
||||
- 18.3.0
|
||||
Content-Length:
|
||||
- '2642'
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/%22Quoted%22%20pages%20can%20be%20tricky.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"xwiki:\"Quoted\"
|
||||
pages can be tricky.WebHome","fullName":"\"Quoted\" pages can be tricky.WebHome","wiki":"xwiki","space":"\"Quoted\"
|
||||
pages can be tricky","name":"WebHome","title":"\"Quoted\" pages can be tricky","rawTitle":"\"Quoted\"
|
||||
pages can be tricky","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"1.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":1,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780387197000,"creator":"XWiki.admin","creatorName":null,"modified":1780387197000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"","content":"When
|
||||
the page title contains quotes, it''s harder to exactly match their page title.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"\"Quoted\"
|
||||
pages can be tricky","name":"\"Quoted\" pages can be tricky","type":"space","url":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/"},{"label":"WebHome","name":"WebHome","type":"document","url":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/"}]},"rights":[],"renderedContent":null}'
|
||||
recorded_at: Tue, 02 Jun 2026 08:17:23 GMT
|
||||
recorded_with: VCR 6.4.0
|
||||
Reference in New Issue
Block a user