mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
Use VCR for stubbing outbound HTTP requests (#13596)
https://community.openproject.org/work_packages/49797
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2020 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.
|
||||
#++
|
||||
|
||||
NEXTCLOUD_LOCAL_OAUTH_CLIENT_ID=
|
||||
NEXTCLOUD_LOCAL_OAUTH_CLIENT_SECRET=
|
||||
|
||||
NEXTCLOUD_LOCAL_OPENPROJECT_UID=
|
||||
NEXTCLOUD_LOCAL_OPENPROJECT_SECRET=
|
||||
NEXTCLOUD_LOCAL_OPENPROJECT_REDIRECT_URI=https://nextcloud.local/index.php/apps/integration_openproject/oauth-redirect
|
||||
|
||||
NEXTCLOUD_LOCAL_OAUTH_CLIENT_ACCESS_TOKEN=
|
||||
NEXTCLOUD_LOCAL_OAUTH_CLIENT_REFRESH_TOKEN=
|
||||
@@ -251,6 +251,8 @@ group :test do
|
||||
gem 'fuubar', '~> 2.5.0'
|
||||
gem 'timecop', '~> 0.9.0'
|
||||
|
||||
# Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests.
|
||||
gem 'vcr'
|
||||
# Mock backend requests (for ruby tests)
|
||||
gem 'webmock', '~> 3.12', require: false
|
||||
|
||||
|
||||
@@ -961,6 +961,7 @@ GEM
|
||||
validate_url (1.0.15)
|
||||
activemodel (>= 3.0.0)
|
||||
public_suffix
|
||||
vcr (6.2.0)
|
||||
view_component (3.5.0)
|
||||
activesupport (>= 5.2.0, < 8.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
@@ -1170,6 +1171,7 @@ DEPENDENCIES
|
||||
typed_dag (~> 2.0.2)
|
||||
tzinfo-data (~> 1.2023.1)
|
||||
validate_url
|
||||
vcr
|
||||
view_component
|
||||
warden (~> 1.2)
|
||||
warden-basic_auth (~> 0.2.1)
|
||||
|
||||
@@ -13,6 +13,17 @@ services:
|
||||
# It must be amended accordingly to OS.
|
||||
- /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro
|
||||
|
||||
backend-test:
|
||||
# Connect the backend-test container to the same network as the backend for nextcloud HTTP interactions
|
||||
networks:
|
||||
- external
|
||||
volumes:
|
||||
# Linux
|
||||
- /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt:ro
|
||||
# Mac OS
|
||||
# - ~/.step/certs:/etc/ssl/certs
|
||||
# - ~/.step/certs:/usr/local/share/ca-certificates
|
||||
|
||||
frontend:
|
||||
networks:
|
||||
- external
|
||||
|
||||
+3
-2
@@ -47,11 +47,12 @@ module Storages::Peripherals::StorageInteraction::Nextcloud
|
||||
service_result = begin
|
||||
response = Util.http(@uri).post(
|
||||
Util.join_uri_path(@uri.path, '/ocs/v2.php/apps/dav/api/v1/direct'),
|
||||
{ fileId: file_link.origin_id },
|
||||
{ fileId: file_link.origin_id }.to_json,
|
||||
{
|
||||
'Authorization' => "Bearer #{token.access_token}",
|
||||
'OCS-APIRequest' => 'true',
|
||||
'Accept' => 'application/json'
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json'
|
||||
}
|
||||
)
|
||||
case response
|
||||
|
||||
@@ -31,23 +31,20 @@
|
||||
require 'spec_helper'
|
||||
require_module_spec_helper
|
||||
|
||||
RSpec.describe Storages::Peripherals::StorageInteraction::Nextcloud::FilesInfoQuery, webmock: true do
|
||||
RSpec.describe Storages::Peripherals::StorageInteraction::Nextcloud::FilesInfoQuery,
|
||||
:vcr, webmock: true do
|
||||
using Storages::Peripherals::ServiceResultRefinements
|
||||
|
||||
let(:user) { create(:user) }
|
||||
let(:url) { 'https://example.com' }
|
||||
let(:origin_user_id) { 'admin' }
|
||||
let(:storage) { build(:nextcloud_storage, :as_not_automatically_managed, host: url) }
|
||||
|
||||
let(:oauth_client) { create(:oauth_client, integration: storage) }
|
||||
let(:token) { create(:oauth_client_token, origin_user_id:, access_token: 'xyz', oauth_client:, user:) }
|
||||
|
||||
before { token }
|
||||
let(:storage) do
|
||||
create(:nextcloud_storage_with_local_connection, :as_not_automatically_managed, oauth_client_token_user: user)
|
||||
end
|
||||
|
||||
subject { described_class.new(storage) }
|
||||
|
||||
describe '#call' do
|
||||
let(:file_ids) { %w[354 355] }
|
||||
let(:file_ids) { %w[182 203 222] }
|
||||
|
||||
context 'without outbound request involved' do
|
||||
context 'with an empty array of file ids' do
|
||||
@@ -69,65 +66,8 @@ RSpec.describe Storages::Peripherals::StorageInteraction::Nextcloud::FilesInfoQu
|
||||
end
|
||||
end
|
||||
|
||||
context 'with outbound request successful' do
|
||||
let(:expected_response_body) do
|
||||
<<~JSON
|
||||
{
|
||||
"ocs": {
|
||||
"meta": {
|
||||
"status": "ok",
|
||||
"statuscode": 100,
|
||||
"message": "OK",
|
||||
"totalitems": "",
|
||||
"itemsperpage": ""
|
||||
},
|
||||
"data": {
|
||||
"354": {
|
||||
"status": "OK",
|
||||
"statuscode": 200,
|
||||
"id": 354,
|
||||
"name": "Demo project (1)",
|
||||
"mtime": 1689162221,
|
||||
"ctime": 0,
|
||||
"mimetype": "application/x-op-directory",
|
||||
"size": 989752,
|
||||
"owner_name": "admin",
|
||||
"owner_id": "admin",
|
||||
"trashed": false,
|
||||
"modifier_name": null,
|
||||
"modifier_id": null,
|
||||
"dav_permissions": "RMGDNVCK",
|
||||
"path": "files/OpenProject/Demo project (1)"
|
||||
},
|
||||
"355": {
|
||||
"status": "OK",
|
||||
"statuscode": 200,
|
||||
"id": 355,
|
||||
"name": "minecraft.jpg",
|
||||
"mtime": 1689162221,
|
||||
"ctime": 0,
|
||||
"mimetype": "image/jpeg",
|
||||
"size": 989752,
|
||||
"owner_name": "admin",
|
||||
"owner_id": "admin",
|
||||
"trashed": false,
|
||||
"modifier_name": null,
|
||||
"modifier_id": null,
|
||||
"dav_permissions": "RMGDNVW",
|
||||
"path": "files/OpenProject/Demo project (1)/minecraft.jpg"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
JSON
|
||||
end
|
||||
|
||||
before do
|
||||
stub_request(:post, "https://example.com/ocs/v1.php/apps/integration_openproject/filesinfo")
|
||||
.with(body: { fileIds: file_ids }.to_json)
|
||||
.to_return(status: 200, body: expected_response_body)
|
||||
end
|
||||
|
||||
context 'with outbound request successful',
|
||||
vcr: 'nextcloud/files_info_query_success' do
|
||||
context 'with an array of file ids' do
|
||||
it 'must return an array of file information when called' do
|
||||
result = subject.call(user:, file_ids:)
|
||||
@@ -135,7 +75,7 @@ RSpec.describe Storages::Peripherals::StorageInteraction::Nextcloud::FilesInfoQu
|
||||
|
||||
result.match(
|
||||
on_success: ->(file_infos) do
|
||||
expect(file_infos.size).to eq(2)
|
||||
expect(file_infos.size).to eq(3)
|
||||
expect(file_infos).to all(be_a(Storages::StorageFileInfo))
|
||||
end,
|
||||
on_failure: ->(error) { fail "Expected success, got #{error}" }
|
||||
@@ -144,14 +84,16 @@ RSpec.describe Storages::Peripherals::StorageInteraction::Nextcloud::FilesInfoQu
|
||||
end
|
||||
end
|
||||
|
||||
context 'with outbound request not authorized' do
|
||||
before do
|
||||
stub_request(:post, "https://example.com/ocs/v1.php/apps/integration_openproject/filesinfo")
|
||||
.with(body: { fileIds: file_ids }.to_json)
|
||||
.to_return(status: 401)
|
||||
end
|
||||
|
||||
context 'with outbound request not authorized',
|
||||
vcr: 'nextcloud/files_info_query_unauthorized' do
|
||||
context 'with an array of file ids' do
|
||||
before do
|
||||
token = build_stubbed(:oauth_client_token, oauth_client: storage.oauth_client)
|
||||
allow(Storages::Peripherals::StorageInteraction::Nextcloud::Util)
|
||||
.to receive(:token)
|
||||
.and_yield(token)
|
||||
end
|
||||
|
||||
it 'must return an error when called' do
|
||||
subject.call(user:, file_ids:).match(
|
||||
on_success: ->(file_infos) { fail "Expected failure, got #{file_infos}" },
|
||||
@@ -162,17 +104,34 @@ RSpec.describe Storages::Peripherals::StorageInteraction::Nextcloud::FilesInfoQu
|
||||
end
|
||||
|
||||
context 'with outbound request not found' do
|
||||
before do
|
||||
stub_request(:post, "https://example.com/ocs/v1.php/apps/integration_openproject/filesinfo")
|
||||
.with(body: { fileIds: file_ids }.to_json)
|
||||
.to_return(status: 404)
|
||||
end
|
||||
context 'with a single file id',
|
||||
vcr: 'nextcloud/files_info_query_not_found' do
|
||||
let(:file_ids) { %w[1234] }
|
||||
|
||||
context 'with an array of file ids' do
|
||||
it 'must return an error when called' do
|
||||
it 'returns an HTTP 200 with individual status code per file ID' do
|
||||
subject.call(user:, file_ids:).match(
|
||||
on_success: ->(file_infos) { fail "Expected failure, got #{file_infos}" },
|
||||
on_failure: ->(error) { expect(error.code).to eq(:not_found) }
|
||||
on_success: ->(file_infos) do
|
||||
expect(file_infos.size).to eq(1)
|
||||
expect(file_infos.first.to_h).to include(status: 'Not Found', status_code: 404)
|
||||
end,
|
||||
on_failure: ->(error) { fail "Expected success, got #{error}" }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with outbound request not authorized' do
|
||||
context 'with multiple file IDs, one of which is not authorized',
|
||||
vcr: 'nextcloud/files_info_query_only_one_not_authorized' do
|
||||
let(:file_ids) { %w[182 1234] }
|
||||
|
||||
it 'returns an HTTP 200 with individual status code per file ID' do
|
||||
subject.call(user:, file_ids:).match(
|
||||
on_success: ->(file_infos) do
|
||||
expect(file_infos.size).to eq(2)
|
||||
expect(file_infos.map(&:status_code)).to contain_exactly(403, 404)
|
||||
end,
|
||||
on_failure: ->(error) { fail "Expected success, got #{error}" }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -39,23 +39,68 @@ FactoryBot.define do
|
||||
oauth_client { build(:oauth_client) }
|
||||
end
|
||||
# rubocop:enable FactoryBot/FactoryAssociationWithStrategy
|
||||
end
|
||||
|
||||
factory :one_drive_storage, class: "Storages::OneDriveStorage" do
|
||||
host { nil }
|
||||
factory :nextcloud_storage,
|
||||
parent: :storage,
|
||||
class: '::Storages::NextcloudStorage' do
|
||||
provider_type { Storages::Storage::PROVIDER_TYPE_NEXTCLOUD }
|
||||
sequence(:host) { |n| "https://host#{n}.example.com" }
|
||||
|
||||
trait :as_automatically_managed do
|
||||
automatically_managed { true }
|
||||
username { 'OpenProject' }
|
||||
password { 'Password123' }
|
||||
end
|
||||
|
||||
factory :nextcloud_storage, class: 'Storages::NextcloudStorage' do
|
||||
sequence(:host) { |n| "https://host#{n}.example.com" }
|
||||
|
||||
trait :as_automatically_managed do
|
||||
automatically_managed { true }
|
||||
username { 'OpenProject' }
|
||||
password { 'Password123' }
|
||||
end
|
||||
|
||||
trait :as_not_automatically_managed do
|
||||
automatically_managed { false }
|
||||
end
|
||||
trait :as_not_automatically_managed do
|
||||
automatically_managed { false }
|
||||
end
|
||||
end
|
||||
|
||||
factory :nextcloud_storage_with_local_connection,
|
||||
parent: :nextcloud_storage,
|
||||
traits: [:as_not_automatically_managed] do
|
||||
transient do
|
||||
oauth_client_token_user { association :user }
|
||||
end
|
||||
|
||||
name { 'Nextcloud Local' }
|
||||
host { 'https://nextcloud.local' }
|
||||
|
||||
initialize_with do
|
||||
Storages::NextcloudStorage.create_or_find_by(attributes.except(:oauth_client, :oauth_application))
|
||||
end
|
||||
|
||||
after(:create) do |storage, evaluator|
|
||||
create(:oauth_client,
|
||||
client_id: ENV.fetch('NEXTCLOUD_LOCAL_OAUTH_CLIENT_ID', 'MISSING_NEXTCLOUD_LOCAL_OAUTH_CLIENT_ID'),
|
||||
client_secret: ENV.fetch('NEXTCLOUD_LOCAL_OAUTH_CLIENT_SECRET', 'MISSING_NEXTCLOUD_LOCAL_OAUTH_CLIENT_SECRET'),
|
||||
integration: storage)
|
||||
|
||||
create(:oauth_application,
|
||||
uid: ENV.fetch('NEXTCLOUD_LOCAL_OPENPROJECT_UID', 'MISSING_NEXTCLOUD_LOCAL_OPENPROJECT_UID'),
|
||||
secret: ENV.fetch('NEXTCLOUD_LOCAL_OPENPROJECT_SECRET', 'MISSING_NEXTCLOUD_LOCAL_OPENPROJECT_SECRET'),
|
||||
redirect_uri: ENV.fetch('NEXTCLOUD_LOCAL_OPENPROJECT_REDIRECT_URI',
|
||||
"https://nextcloud.local/index.php/apps/integration_openproject/oauth-redirect"),
|
||||
scopes: 'api_v3',
|
||||
integration: storage)
|
||||
|
||||
create(:oauth_client_token,
|
||||
oauth_client: storage.oauth_client,
|
||||
user: evaluator.oauth_client_token_user,
|
||||
access_token: ENV.fetch('NEXTCLOUD_LOCAL_OAUTH_CLIENT_ACCESS_TOKEN',
|
||||
'MISSING_NEXTCLOUD_LOCAL_OAUTH_CLIENT_ACCESS_TOKEN'),
|
||||
refresh_token: ENV.fetch('NEXTCLOUD_LOCAL_OAUTH_CLIENT_REFRESH_TOKEN',
|
||||
'MISSING_NEXTCLOUD_LOCAL_OAUTH_CLIENT_REFRESH_TOKEN'),
|
||||
token_type: 'bearer',
|
||||
origin_user_id: 'admin')
|
||||
end
|
||||
end
|
||||
|
||||
factory :one_drive_storage,
|
||||
parent: :storage,
|
||||
class: '::Storages::OneDriveStorage' do
|
||||
host { nil }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
require 'spec_helper'
|
||||
require 'dry/container/stub'
|
||||
|
||||
# Record Storages Cassettes in module
|
||||
VCR.configure do |config|
|
||||
config.cassette_library_dir = 'modules/storages/spec/support/fixtures/vcr_cassettes'
|
||||
end
|
||||
|
||||
# Loads files from relative support/ directory
|
||||
Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require f }
|
||||
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: post
|
||||
uri: https://nextcloud.local/ocs/v1.php/apps/integration_openproject/filesinfo
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"fileIds":["1234"]}'
|
||||
headers:
|
||||
Authorization:
|
||||
- Bearer L49hIQGzShBYfjblMAtTDtT15rtZ8wagxFIbwQTzD0LRIfUOBmOYz9wY5pvIY9zkLMpXLcK9
|
||||
Accept:
|
||||
- application/json
|
||||
Content-Type:
|
||||
- application/json
|
||||
Ocs-Apirequest:
|
||||
- 'true'
|
||||
Accept-Encoding:
|
||||
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
||||
User-Agent:
|
||||
- Ruby
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Access-Control-Allow-Credentials:
|
||||
- 'true'
|
||||
Cache-Control:
|
||||
- no-cache, no-store, must-revalidate
|
||||
Content-Length:
|
||||
- '154'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Wed, 30 Aug 2023 15:26:14 GMT
|
||||
Expires:
|
||||
- Thu, 19 Nov 1981 08:52:00 GMT
|
||||
Feature-Policy:
|
||||
- autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone
|
||||
'none';payment 'none'
|
||||
Pragma:
|
||||
- no-cache
|
||||
Referrer-Policy:
|
||||
- no-referrer
|
||||
Server:
|
||||
- Apache/2.4.56 (Debian)
|
||||
Set-Cookie:
|
||||
- __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100
|
||||
23:59:59 GMT; SameSite=lax
|
||||
- __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri,
|
||||
31-Dec-2100 23:59:59 GMT; SameSite=strict
|
||||
- oc_sessionPassphrase=mubP6L1KhzkAbwW%2BdVOdSsS10ZEeOJUYFAEVeqbp1%2BA37vA9h98ve5%2BxUBz1zPeIpCJRBNvPfF1sOmZBn5HM8qGFwvc9b9scbO4E9GovlEPYW0X%2B1WMN0eKqmW45nR7A;
|
||||
path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=cc97b31ff8dede5d34607ee68aff20e8; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=cc97b31ff8dede5d34607ee68aff20e8; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=cc97b31ff8dede5d34607ee68aff20e8; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=cc97b31ff8dede5d34607ee68aff20e8; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=cc97b31ff8dede5d34607ee68aff20e8; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=cc97b31ff8dede5d34607ee68aff20e8; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=cc97b31ff8dede5d34607ee68aff20e8; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=cc97b31ff8dede5d34607ee68aff20e8; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=cc97b31ff8dede5d34607ee68aff20e8; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=ff3381b14b648bcb48e62a82cbb42c87; path=/; secure; HttpOnly; SameSite=Lax
|
||||
Vary:
|
||||
- Origin
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Powered-By:
|
||||
- PHP/8.2.8
|
||||
X-Request-Id:
|
||||
- v3tT2TMs2xjqxJOvWJ2f
|
||||
X-Robots-Tag:
|
||||
- noindex, nofollow
|
||||
X-Xss-Protection:
|
||||
- 1; mode=block
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"ocs":{"meta":{"status":"ok","statuscode":100,"message":"OK","totalitems":"","itemsperpage":""},"data":{"1234":{"status":"Not
|
||||
Found","statuscode":404}}}}'
|
||||
recorded_at: Wed, 30 Aug 2023 15:26:14 GMT
|
||||
recorded_with: VCR 6.2.0
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: post
|
||||
uri: https://nextcloud.local/ocs/v1.php/apps/integration_openproject/filesinfo
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"fileIds":["182","1234"]}'
|
||||
headers:
|
||||
Authorization:
|
||||
- Bearer L49hIQGzShBYfjblMAtTDtT15rtZ8wagxFIbwQTzD0LRIfUOBmOYz9wY5pvIY9zkLMpXLcK9
|
||||
Accept:
|
||||
- application/json
|
||||
Content-Type:
|
||||
- application/json
|
||||
Ocs-Apirequest:
|
||||
- 'true'
|
||||
Accept-Encoding:
|
||||
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
||||
User-Agent:
|
||||
- Ruby
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Access-Control-Allow-Credentials:
|
||||
- 'true'
|
||||
Cache-Control:
|
||||
- no-cache, no-store, must-revalidate
|
||||
Content-Length:
|
||||
- '200'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Wed, 30 Aug 2023 15:42:44 GMT
|
||||
Expires:
|
||||
- Thu, 19 Nov 1981 08:52:00 GMT
|
||||
Feature-Policy:
|
||||
- autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone
|
||||
'none';payment 'none'
|
||||
Pragma:
|
||||
- no-cache
|
||||
Referrer-Policy:
|
||||
- no-referrer
|
||||
Server:
|
||||
- Apache/2.4.56 (Debian)
|
||||
Set-Cookie:
|
||||
- __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100
|
||||
23:59:59 GMT; SameSite=lax
|
||||
- __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri,
|
||||
31-Dec-2100 23:59:59 GMT; SameSite=strict
|
||||
- oc_sessionPassphrase=jrT6r0yM%2BFS1HHed4hww77b%2B4Nv2Sf1UYogAKMFI2xarG0FxxSDQcuuwf%2FhVigK4HNXAOjdtVY%2BcAZJvM3KyVy%2FZIVkiIH7C3CR%2FQEFybCQPE2ecRh9dnS6UkGX7nz1R;
|
||||
path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=2097f255d8b54122037144f5504cd33e; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=69f515e7c5bfb387de23f92cf0bbebcc; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=69f515e7c5bfb387de23f92cf0bbebcc; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=69f515e7c5bfb387de23f92cf0bbebcc; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=69f515e7c5bfb387de23f92cf0bbebcc; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=69f515e7c5bfb387de23f92cf0bbebcc; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=69f515e7c5bfb387de23f92cf0bbebcc; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=69f515e7c5bfb387de23f92cf0bbebcc; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=69f515e7c5bfb387de23f92cf0bbebcc; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=69f515e7c5bfb387de23f92cf0bbebcc; path=/; secure; HttpOnly; SameSite=Lax
|
||||
Vary:
|
||||
- Origin
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Powered-By:
|
||||
- PHP/8.2.8
|
||||
X-Request-Id:
|
||||
- RqDl34ieFVXiEvFcPeJV
|
||||
X-Robots-Tag:
|
||||
- noindex, nofollow
|
||||
X-Xss-Protection:
|
||||
- 1; mode=block
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"ocs":{"meta":{"status":"ok","statuscode":100,"message":"OK","totalitems":"","itemsperpage":""},"data":{"182":{"status":"Forbidden","statuscode":403},"1234":{"status":"Not
|
||||
Found","statuscode":404}}}}'
|
||||
recorded_at: Wed, 30 Aug 2023 15:42:45 GMT
|
||||
recorded_with: VCR 6.2.0
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: post
|
||||
uri: https://nextcloud.local/ocs/v1.php/apps/integration_openproject/filesinfo
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"fileIds":["182","203","222"]}'
|
||||
headers:
|
||||
Authorization:
|
||||
- Bearer L49hIQGzShBYfjblMAtTDtT15rtZ8wagxFIbwQTzD0LRIfUOBmOYz9wY5pvIY9zkLMpXLcK9
|
||||
Accept:
|
||||
- application/json
|
||||
Content-Type:
|
||||
- application/json
|
||||
Ocs-Apirequest:
|
||||
- 'true'
|
||||
Accept-Encoding:
|
||||
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
||||
User-Agent:
|
||||
- Ruby
|
||||
response:
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
headers:
|
||||
Access-Control-Allow-Credentials:
|
||||
- 'true'
|
||||
Cache-Control:
|
||||
- no-cache, no-store, must-revalidate
|
||||
Content-Length:
|
||||
- '577'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Wed, 30 Aug 2023 15:45:26 GMT
|
||||
Expires:
|
||||
- Thu, 19 Nov 1981 08:52:00 GMT
|
||||
Feature-Policy:
|
||||
- autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone
|
||||
'none';payment 'none'
|
||||
Pragma:
|
||||
- no-cache
|
||||
Referrer-Policy:
|
||||
- no-referrer
|
||||
Server:
|
||||
- Apache/2.4.56 (Debian)
|
||||
Set-Cookie:
|
||||
- __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100
|
||||
23:59:59 GMT; SameSite=lax
|
||||
- __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri,
|
||||
31-Dec-2100 23:59:59 GMT; SameSite=strict
|
||||
- oc_sessionPassphrase=bZysxrG%2Fl16DjX2dkVG88Pgrm1tYYZ7EzUwAVCaBnEnVxo8pbldMJx2U9QF%2FXm%2Blyz8WZSNH10txYYv%2BXIBIOhZQCpNue%2BiOgD4BTSq%2BBL4VlFQ4OEnyKTMeCwrk1vr%2F;
|
||||
path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=57a237ced5d8cbea7fa030db90ed0f3f; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=e4353119162ec0f0020b925c614ce423; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=e4353119162ec0f0020b925c614ce423; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=e4353119162ec0f0020b925c614ce423; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=e4353119162ec0f0020b925c614ce423; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=e4353119162ec0f0020b925c614ce423; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=e4353119162ec0f0020b925c614ce423; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=e4353119162ec0f0020b925c614ce423; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=e4353119162ec0f0020b925c614ce423; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=e4353119162ec0f0020b925c614ce423; path=/; secure; HttpOnly; SameSite=Lax
|
||||
Vary:
|
||||
- Origin
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Powered-By:
|
||||
- PHP/8.2.8
|
||||
X-Request-Id:
|
||||
- Oi4F9CkhBWYYmLeEmoUp
|
||||
X-Robots-Tag:
|
||||
- noindex, nofollow
|
||||
X-Xss-Protection:
|
||||
- 1; mode=block
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"ocs":{"meta":{"status":"ok","statuscode":100,"message":"OK","totalitems":"","itemsperpage":""},"data":{"182":{"status":"Forbidden","statuscode":403},"203":{"status":"Forbidden","statuscode":403},"222":{"status":"OK","statuscode":200,"id":222,"name":"Screenshot
|
||||
2023-08-15 at 3.00.54 PM.jpg","mtime":1692187580,"ctime":0,"mimetype":"image\/jpeg","size":81944,"owner_name":"member","owner_id":"member","trashed":false,"modifier_name":null,"modifier_id":null,"dav_permissions":"RMGDNVW","path":"files\/OpenProject\/Scrum
|
||||
project (2)\/Screenshot 2023-08-15 at 3.00.54 PM.jpg"}}}}'
|
||||
recorded_at: Wed, 30 Aug 2023 15:45:26 GMT
|
||||
recorded_with: VCR 6.2.0
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
---
|
||||
http_interactions:
|
||||
- request:
|
||||
method: post
|
||||
uri: https://nextcloud.local/ocs/v1.php/apps/integration_openproject/filesinfo
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"fileIds":["182","203","222"]}'
|
||||
headers:
|
||||
Authorization:
|
||||
- Bearer 1234567890-1
|
||||
Accept:
|
||||
- application/json
|
||||
Content-Type:
|
||||
- application/json
|
||||
Ocs-Apirequest:
|
||||
- 'true'
|
||||
Accept-Encoding:
|
||||
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
||||
User-Agent:
|
||||
- Ruby
|
||||
response:
|
||||
status:
|
||||
code: 401
|
||||
message: Unauthorized
|
||||
headers:
|
||||
Access-Control-Allow-Credentials:
|
||||
- 'true'
|
||||
Cache-Control:
|
||||
- no-cache, no-store, must-revalidate
|
||||
Content-Length:
|
||||
- '140'
|
||||
Content-Security-Policy:
|
||||
- default-src 'none';base-uri 'none';manifest-src 'self';frame-ancestors 'none'
|
||||
Content-Type:
|
||||
- application/json; charset=utf-8
|
||||
Date:
|
||||
- Thu, 31 Aug 2023 15:56:02 GMT
|
||||
Expires:
|
||||
- Thu, 19 Nov 1981 08:52:00 GMT
|
||||
Feature-Policy:
|
||||
- autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone
|
||||
'none';payment 'none'
|
||||
Pragma:
|
||||
- no-cache
|
||||
Referrer-Policy:
|
||||
- no-referrer
|
||||
Server:
|
||||
- Apache/2.4.56 (Debian)
|
||||
Set-Cookie:
|
||||
- __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100
|
||||
23:59:59 GMT; SameSite=lax
|
||||
- __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri,
|
||||
31-Dec-2100 23:59:59 GMT; SameSite=strict
|
||||
- oc_sessionPassphrase=jerIWxh2u207KZvn8P9QfqUQqhxH1PU9dwZGLgmFmmE7YvuUvHLkMAXQJ6cxw0Tv622PCSD3z4wvuv%2BQZYmocMUcRJxkjuSMaUrwXB83Ys2%2BO%2BegSfLT12NgAQPSGY82;
|
||||
path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=40ab489740e67cfe180e2c0fce9972a4; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=8e5f3e155930f7d2a03ce41bb8c67e49; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=8e5f3e155930f7d2a03ce41bb8c67e49; path=/; secure; HttpOnly; SameSite=Lax
|
||||
- ocybhqi440sc=8e5f3e155930f7d2a03ce41bb8c67e49; path=/; secure; HttpOnly; SameSite=Lax
|
||||
Vary:
|
||||
- Origin
|
||||
X-Content-Type-Options:
|
||||
- nosniff
|
||||
X-Frame-Options:
|
||||
- SAMEORIGIN
|
||||
X-Permitted-Cross-Domain-Policies:
|
||||
- none
|
||||
X-Powered-By:
|
||||
- PHP/8.2.8
|
||||
X-Request-Id:
|
||||
- HbnpSYoZ0evEYxmtZRPO
|
||||
X-Robots-Tag:
|
||||
- noindex, nofollow
|
||||
X-Xss-Protection:
|
||||
- 1; mode=block
|
||||
body:
|
||||
encoding: UTF-8
|
||||
string: '{"ocs":{"meta":{"status":"failure","statuscode":997,"message":"Current
|
||||
user is not logged in","totalitems":"","itemsperpage":""},"data":[]}}'
|
||||
recorded_at: Thu, 31 Aug 2023 15:56:02 GMT
|
||||
recorded_with: VCR 6.2.0
|
||||
@@ -0,0 +1,53 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2023 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 'vcr'
|
||||
|
||||
VCR.configure do |config|
|
||||
config.cassette_library_dir = 'spec/support/fixtures/vcr_cassettes'
|
||||
config.hook_into :webmock
|
||||
config.configure_rspec_metadata!
|
||||
config.before_record do |i|
|
||||
i.response.body.force_encoding('UTF-8')
|
||||
end
|
||||
end
|
||||
|
||||
VCR.turn_off!
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.around(:example, :vcr) do |example|
|
||||
# Only enable VCR's webmock integration for tests tagged with :vcr otherwise interferes with WebMock
|
||||
# See: https://github.com/vcr/vcr/issues/146
|
||||
#
|
||||
VCR.turn_on!
|
||||
example.run
|
||||
ensure
|
||||
# Switch off VCR to prevent VCR from interfering with other tests
|
||||
VCR.turn_off!
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user