pisoni 1.29.1 → 1.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/Gemfile +3 -2
- data/Makefile +14 -68
- data/README.md +6 -12
- data/lib/3scale/core/api_client/operations.rb +6 -1
- data/lib/3scale/core/api_client/support.rb +6 -0
- data/lib/3scale/core/application.rb +12 -10
- data/lib/3scale/core/application_key.rb +2 -4
- data/lib/3scale/core/application_referrer_filter.rb +1 -1
- data/lib/3scale/core/utilization.rb +1 -1
- data/lib/3scale/core/version.rb +1 -1
- data/lib/3scale/core.rb +2 -9
- data/pisoni.gemspec +6 -6
- data/podman-compose.yml +19 -0
- data/spec/application_key_spec.rb +4 -4
- data/spec/application_referrer_filter_spec.rb +5 -4
- data/spec/application_spec.rb +97 -4
- data/spec/spec_helper.rb +7 -3
- data/spec/utilization_spec.rb +10 -0
- metadata +32 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5804502f649cd2bb89c6a7e696684c4226c53430e4c132e4f82fd755d4e1a96d
|
|
4
|
+
data.tar.gz: 354583b6d17ebdf0a5ed15c7121ab5b550ce008e3383c1fab17ac5f8a66c8a97
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a25cc7464fe34178899e3239fc39d0ce394e70dfb68f9cc6f4ebe0c062dfe3f72975d2158132df9fadb65d488f18fb6f19b0fc3d0d803fb0093fb3f5f976a100
|
|
7
|
+
data.tar.gz: 8343b9dae4eac7195396cc48563a3df20c07b5402dd4ef5010a100bda895833664845131e91c0838d7788f32258cdb6763989c8cf02ed45e337c4748e3236e6b
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes to Pisoni will be tracked in this document.
|
|
4
4
|
|
|
5
|
+
## 1.31.0 - 2026-07-03
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Batch update support for applications via `Application.save_batch`. [#37](https://github.com/3scale/pisoni/pull/37)
|
|
10
|
+
- Qlty integration for code quality and coverage reporting, replacing codeclimate. [#39](https://github.com/3scale/pisoni/pull/39)
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Updated Faraday dependency to allow >= 2.14.3 (removed <= 2.9 cap). [#36](https://github.com/3scale/pisoni/pull/36)
|
|
15
|
+
- Minimum Ruby version bumped from 2.6 to 3.0 (required by Faraday >= 2.9). [#36](https://github.com/3scale/pisoni/pull/36)
|
|
16
|
+
- CircleCI now requires manual approval before running builds. [#38](https://github.com/3scale/pisoni/pull/38)
|
|
17
|
+
- Pinned minitest to ~> 5.0 to prevent breakage from minitest 6. [#36](https://github.com/3scale/pisoni/pull/36)
|
|
18
|
+
|
|
19
|
+
## 1.30.0 - 2024-02-29
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Fixed the issue with fetching utilization and managing referrer filters for applications with special characters in the
|
|
24
|
+
application IDs by escaping them. [#33](https://github.com/3scale/pisoni/pull/33)
|
|
25
|
+
- Upgrade dependencies, specifically `faraday` and `json`, making Ruby 2.6 the minimum supported version. [#34](https://github.com/3scale/pisoni/pull/34)
|
|
26
|
+
|
|
5
27
|
## 1.29.1 - 2023-11-30
|
|
6
28
|
|
|
7
29
|
### Changed
|
data/Gemfile
CHANGED
|
@@ -3,8 +3,9 @@ source "https://rubygems.org"
|
|
|
3
3
|
gemspec
|
|
4
4
|
|
|
5
5
|
group :test do
|
|
6
|
-
gem 'minitest'
|
|
7
|
-
gem
|
|
6
|
+
gem 'minitest', '~> 5.0'
|
|
7
|
+
gem 'simplecov', require: false
|
|
8
|
+
gem 'simplecov_json_formatter', require: false
|
|
8
9
|
end
|
|
9
10
|
|
|
10
11
|
group :development, :test do
|
data/Makefile
CHANGED
|
@@ -1,78 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
PROJECT_PATH := $(patsubst %/,%,$(dir $(MKFILE_PATH)))
|
|
1
|
+
COMPOSE ?= podman-compose
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
.PHONY: deps_up
|
|
4
|
+
deps_up:
|
|
5
|
+
$(COMPOSE) up -d
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
CI_IMAGE_REPO ?= quay.io/3scale
|
|
10
|
-
CI_IMAGE_NAME ?= pisoni-ci
|
|
11
|
-
CI_IMAGE ?= $(CI_IMAGE_REPO)/$(CI_IMAGE_NAME)
|
|
12
|
-
CI_DOCKERFILE ?= $(PROJECT_PATH)/docker/Dockerfile.ci
|
|
13
|
-
|
|
14
|
-
include $(PROJECT_PATH)/mk/ci-image.mk
|
|
15
|
-
include $(PROJECT_PATH)/mk/ci.mk
|
|
16
|
-
|
|
17
|
-
all: clean pull build test
|
|
18
|
-
|
|
19
|
-
$(call ci_build_target,ci-pull,pull)
|
|
20
|
-
$(call ci_build_target,ci-test,test)
|
|
21
|
-
$(call ci_build_target,ci-compose-config,compose-config)
|
|
7
|
+
.PHONY: deps_down
|
|
8
|
+
deps_down:
|
|
9
|
+
- $(COMPOSE) down
|
|
22
10
|
|
|
23
|
-
.PHONY:
|
|
24
|
-
|
|
25
|
-
|
|
11
|
+
.PHONY: run_test
|
|
12
|
+
run_test:
|
|
13
|
+
THREESCALE_CORE_INTERNAL_API=http://user:password@localhost:3001 bundle exec rake test
|
|
26
14
|
|
|
27
15
|
.PHONY: test
|
|
28
|
-
test: run_test
|
|
29
|
-
|
|
30
|
-
.PHONY: bash
|
|
31
|
-
bash: run clean
|
|
32
|
-
|
|
33
|
-
.PHONY: dev
|
|
34
|
-
dev: run
|
|
35
|
-
|
|
36
|
-
.PHONY: run
|
|
37
|
-
run: compose
|
|
38
|
-
$(COMPOSE) run --rm test /bin/bash
|
|
39
|
-
|
|
40
|
-
.PHONY: run_test
|
|
41
|
-
run_test: compose
|
|
42
|
-
$(COMPOSE) run --rm -e COVERAGE=$(COVERAGE) test
|
|
16
|
+
test: deps_up run_test deps_down
|
|
43
17
|
|
|
44
18
|
.PHONY: license_finder
|
|
45
|
-
license_finder:
|
|
46
|
-
$(COMPOSE) run --rm -e COVERAGE=$(COVERAGE)
|
|
47
|
-
|
|
48
|
-
.PHONY: build
|
|
49
|
-
build: compose
|
|
50
|
-
$(COMPOSE) build
|
|
51
|
-
|
|
52
|
-
.PHONY: pull
|
|
53
|
-
pull: compose
|
|
54
|
-
$(COMPOSE) pull
|
|
19
|
+
license_finder:
|
|
20
|
+
$(COMPOSE) run --rm -e COVERAGE=$(COVERAGE) pisoni bundle exec rake license_finder:check
|
|
55
21
|
|
|
56
22
|
.PHONY: stop
|
|
57
|
-
stop:
|
|
23
|
+
stop:
|
|
58
24
|
$(COMPOSE) stop
|
|
59
|
-
|
|
60
|
-
.PHONY: clean
|
|
61
|
-
clean: stop
|
|
62
|
-
- $(COMPOSE) rm -f -v
|
|
63
|
-
|
|
64
|
-
.PHONY: up
|
|
65
|
-
up: compose
|
|
66
|
-
$(COMPOSE) up --abort-on-container-exit --exit-code-from test -t 2 --remove-orphans
|
|
67
|
-
|
|
68
|
-
.PHONY: down
|
|
69
|
-
down: clean
|
|
70
|
-
- $(COMPOSE) down
|
|
71
|
-
|
|
72
|
-
.PHONY: destroy
|
|
73
|
-
destroy: clean
|
|
74
|
-
$(COMPOSE) down -v --remove-orphans --rmi local
|
|
75
|
-
|
|
76
|
-
.PHONY: destroy-all
|
|
77
|
-
destroy-all: clean
|
|
78
|
-
$(COMPOSE) down -v --remove-orphans --rmi all
|
data/README.md
CHANGED
|
@@ -23,22 +23,16 @@ where x.y.z is the version you aim for.
|
|
|
23
23
|
|
|
24
24
|
## Development
|
|
25
25
|
|
|
26
|
-
###
|
|
26
|
+
### Running tests with `make` and `podman-compose`
|
|
27
27
|
|
|
28
|
-
We are using [
|
|
29
|
-
|
|
28
|
+
We are using [podman-compose](https://github.com/containers/podman-compose) to run the dependencies (redis and apisonator) for the tests.
|
|
29
|
+
You need to have it installed locally.
|
|
30
30
|
|
|
31
|
-
You
|
|
32
|
-
one used for actual testing and development.
|
|
31
|
+
You can run the test suite (with the required dependencies) by executing `make test`.
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
a container in which the code is sync'ed back to your host.
|
|
33
|
+
For cleaning up the dependencies containers, you can run `make deps_down`.
|
|
36
34
|
|
|
37
|
-
|
|
38
|
-
`make destroy`. If you want to also get rid of pulled images, run `make
|
|
39
|
-
destroy-all`.
|
|
40
|
-
|
|
41
|
-
### Running tests
|
|
35
|
+
### Running tests locally
|
|
42
36
|
|
|
43
37
|
You can run both tests & specs with:
|
|
44
38
|
|
|
@@ -63,6 +63,11 @@ module ThreeScale
|
|
|
63
63
|
api_do_delete(attributes, api_options, &blk)[:ok]
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
+
def api_update_batch(attributes, api_options = {}, &blk)
|
|
67
|
+
ret = api_do_put(attributes, api_options.merge(prefix: ''), &blk)
|
|
68
|
+
ret[:response_json]
|
|
69
|
+
end
|
|
70
|
+
|
|
66
71
|
# Helpers
|
|
67
72
|
|
|
68
73
|
def api_do_get(attributes, api_options = {}, &blk)
|
|
@@ -106,7 +111,7 @@ module ThreeScale
|
|
|
106
111
|
else
|
|
107
112
|
Core.faraday.send method, uri, attributes.to_json
|
|
108
113
|
end
|
|
109
|
-
rescue Faraday::
|
|
114
|
+
rescue Faraday::ClientError, SystemCallError => e
|
|
110
115
|
raise ConnectionError, e
|
|
111
116
|
end
|
|
112
117
|
private :api_http
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
|
|
1
3
|
module ThreeScale
|
|
2
4
|
module Core
|
|
3
5
|
module APIClient
|
|
@@ -38,6 +40,10 @@ module ThreeScale
|
|
|
38
40
|
@default_prefix = prefix
|
|
39
41
|
end
|
|
40
42
|
|
|
43
|
+
def url_encode(str)
|
|
44
|
+
ERB::Util.url_encode(str)
|
|
45
|
+
end
|
|
46
|
+
|
|
41
47
|
private
|
|
42
48
|
|
|
43
49
|
def internal_api_error(status)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'cgi'
|
|
2
|
-
|
|
3
1
|
module ThreeScale
|
|
4
2
|
module Core
|
|
5
3
|
class Application < APIClient::Resource
|
|
@@ -18,19 +16,20 @@ module ThreeScale
|
|
|
18
16
|
private_class_method :base_uri
|
|
19
17
|
|
|
20
18
|
def self.app_uri(service_id, id)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"#{base_uri(service_id)}#{escaped_id}"
|
|
19
|
+
"#{base_uri(service_id)}#{url_encode(id)}"
|
|
24
20
|
end
|
|
25
21
|
private_class_method :app_uri
|
|
26
22
|
|
|
27
23
|
def self.key_uri(service_id, key)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"#{base_uri(service_id)}key/#{escaped_key}"
|
|
24
|
+
"#{base_uri(service_id)}key/#{url_encode(key)}"
|
|
31
25
|
end
|
|
32
26
|
private_class_method :key_uri
|
|
33
27
|
|
|
28
|
+
def self.batch_uri(service_id)
|
|
29
|
+
"#{base_uri(service_id)}batch"
|
|
30
|
+
end
|
|
31
|
+
private_class_method :batch_uri
|
|
32
|
+
|
|
34
33
|
def self.load(service_id, id)
|
|
35
34
|
api_read({}, uri: app_uri(service_id, id))
|
|
36
35
|
end
|
|
@@ -44,6 +43,10 @@ module ThreeScale
|
|
|
44
43
|
api_delete({}, uri: app_uri(service_id, id))
|
|
45
44
|
end
|
|
46
45
|
|
|
46
|
+
def self.save_batch(service_id, applications)
|
|
47
|
+
api_update_batch({ applications: applications }, uri: batch_uri(service_id))
|
|
48
|
+
end
|
|
49
|
+
|
|
47
50
|
def initialize(attributes = {})
|
|
48
51
|
@state = :active
|
|
49
52
|
super(attributes)
|
|
@@ -77,8 +80,7 @@ module ThreeScale
|
|
|
77
80
|
|
|
78
81
|
def self.save_id_by_key(service_id, user_key, id)
|
|
79
82
|
raise ApplicationHasInconsistentData.new(id, user_key) if (service_id.nil? || id.nil? || user_key.nil? || service_id=="" || id=="" || user_key=="")
|
|
80
|
-
|
|
81
|
-
ret = api_do_put({}, uri: "#{app_uri(service_id, id)}/key/#{escaped_key}")
|
|
83
|
+
ret = api_do_put({}, uri: "#{app_uri(service_id, id)}/key/#{url_encode(user_key)}")
|
|
82
84
|
ret[:ok]
|
|
83
85
|
end
|
|
84
86
|
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'cgi'
|
|
2
|
-
|
|
3
1
|
module ThreeScale
|
|
4
2
|
module Core
|
|
5
3
|
class ApplicationKey < APIClient::Resource
|
|
@@ -23,12 +21,12 @@ module ThreeScale
|
|
|
23
21
|
end
|
|
24
22
|
|
|
25
23
|
def self.base_uri(service_id, application_id)
|
|
26
|
-
"#{default_uri}#{service_id}/applications/#{
|
|
24
|
+
"#{default_uri}#{service_id}/applications/#{url_encode(application_id)}/keys/"
|
|
27
25
|
end
|
|
28
26
|
private_class_method :base_uri
|
|
29
27
|
|
|
30
28
|
def self.application_key_uri(service_id, application_id, value = '')
|
|
31
|
-
"#{base_uri(service_id, application_id)}#{
|
|
29
|
+
"#{base_uri(service_id, application_id)}#{url_encode(value)}"
|
|
32
30
|
end
|
|
33
31
|
private_class_method :application_key_uri
|
|
34
32
|
end
|
|
@@ -25,7 +25,7 @@ module ThreeScale
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def self.base_uri(service_id, application_id)
|
|
28
|
-
"#{default_uri}#{service_id}/applications/#{application_id}/referrer_filters"
|
|
28
|
+
"#{default_uri}#{service_id}/applications/#{url_encode(application_id)}/referrer_filters"
|
|
29
29
|
end
|
|
30
30
|
private_class_method :base_uri
|
|
31
31
|
end
|
|
@@ -6,7 +6,7 @@ module ThreeScale
|
|
|
6
6
|
default_uri '/internal/services/'
|
|
7
7
|
|
|
8
8
|
def self.utilization_uri(service_id, app_id)
|
|
9
|
-
"#{default_uri}#{service_id}/applications/#{app_id}/utilization/"
|
|
9
|
+
"#{default_uri}#{service_id}/applications/#{url_encode(app_id)}/utilization/"
|
|
10
10
|
end
|
|
11
11
|
private_class_method :utilization_uri
|
|
12
12
|
|
data/lib/3scale/core/version.rb
CHANGED
data/lib/3scale/core.rb
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
require 'uri'
|
|
2
2
|
require 'json'
|
|
3
3
|
require 'faraday'
|
|
4
|
-
require '
|
|
5
|
-
|
|
6
|
-
# Warn that Faraday < 0.13 and Net::HTTP::Persistent >= 3.0.0 don't mix well
|
|
7
|
-
if Faraday::VERSION =~ /0\.([0-9]|1[012])\.\d+/ &&
|
|
8
|
-
Net::HTTP::Persistent::VERSION =~ /^[^012]\.\d+\.\d+/
|
|
9
|
-
warn 'The combination of faraday < 0.13 and net-http-persistent 3.0+ is ' \
|
|
10
|
-
'known to have issues. See https://github.com/lostisland/faraday/issues/617'
|
|
11
|
-
end
|
|
4
|
+
require 'faraday/net_http_persistent'
|
|
12
5
|
|
|
13
6
|
require '3scale/core/version'
|
|
14
7
|
require '3scale/core/logger'
|
|
@@ -56,7 +49,7 @@ module ThreeScale
|
|
|
56
49
|
@password = uri.password
|
|
57
50
|
end
|
|
58
51
|
|
|
59
|
-
@faraday.
|
|
52
|
+
@faraday.set_basic_auth(@username, @password) if @username || @password
|
|
60
53
|
@faraday
|
|
61
54
|
end
|
|
62
55
|
|
data/pisoni.gemspec
CHANGED
|
@@ -18,12 +18,12 @@ Gem::Specification.new do |s|
|
|
|
18
18
|
s.description = 'Client for the Apisonator internal API for model data.'
|
|
19
19
|
s.license = 'Apache-2.0'
|
|
20
20
|
|
|
21
|
-
s.
|
|
22
|
-
s.
|
|
23
|
-
s.
|
|
24
|
-
s.
|
|
21
|
+
s.add_runtime_dependency 'faraday', '~> 2.0', '>= 2.14.3'
|
|
22
|
+
s.add_runtime_dependency 'json', '~> 2.7', '>= 2.7.1'
|
|
23
|
+
s.add_runtime_dependency 'injectedlogger', '0.0.13'
|
|
24
|
+
s.add_runtime_dependency 'faraday-net_http_persistent', '~> 2.1'
|
|
25
25
|
|
|
26
|
-
s.add_development_dependency 'rake'
|
|
26
|
+
s.add_development_dependency 'rake', '~> 13.1'
|
|
27
27
|
|
|
28
28
|
s.files = `git ls-files`.split($/).reject do |f| [
|
|
29
29
|
%r{^\.[^\/]},
|
|
@@ -39,5 +39,5 @@ Gem::Specification.new do |s|
|
|
|
39
39
|
|
|
40
40
|
s.rdoc_options = ["--charset=UTF-8"]
|
|
41
41
|
|
|
42
|
-
s.required_ruby_version = '>=
|
|
42
|
+
s.required_ruby_version = '>= 3.0.0'
|
|
43
43
|
end
|
data/podman-compose.yml
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
version: '3'
|
|
2
|
+
services:
|
|
3
|
+
|
|
4
|
+
redis:
|
|
5
|
+
image: redis:6.2-alpine
|
|
6
|
+
|
|
7
|
+
apisonator:
|
|
8
|
+
image: quay.io/3scale/apisonator:latest
|
|
9
|
+
ports:
|
|
10
|
+
- "3001:3001"
|
|
11
|
+
environment:
|
|
12
|
+
CONFIG_INTERNAL_API_USER: user
|
|
13
|
+
CONFIG_INTERNAL_API_PASSWORD: password
|
|
14
|
+
CONFIG_QUEUES_MASTER_NAME: redis://redis:6379
|
|
15
|
+
CONFIG_REDIS_PROXY: redis://redis:6379
|
|
16
|
+
RACK_ENV: test
|
|
17
|
+
command: 3scale_backend start -p 3001
|
|
18
|
+
depends_on:
|
|
19
|
+
- redis
|
|
@@ -59,7 +59,7 @@ module ThreeScale
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
describe 'with a key that contains special chars (*, _, etc.)' do
|
|
62
|
-
let(:key) {
|
|
62
|
+
let(:key) { SPECIAL_CHARACTERS }
|
|
63
63
|
|
|
64
64
|
before do
|
|
65
65
|
ApplicationKey.delete(service_id, app_id, key)
|
|
@@ -74,8 +74,8 @@ module ThreeScale
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
describe 'with app ID that contains special characters ({, $, ? etc.)' do
|
|
77
|
-
let(:app_id) {
|
|
78
|
-
let(:key) {
|
|
77
|
+
let(:app_id) { SPECIAL_CHARACTERS }
|
|
78
|
+
let(:key) { SPECIAL_CHARACTERS }
|
|
79
79
|
|
|
80
80
|
before do
|
|
81
81
|
ApplicationKey.delete(service_id, app_id, key)
|
|
@@ -119,7 +119,7 @@ module ThreeScale
|
|
|
119
119
|
end
|
|
120
120
|
|
|
121
121
|
describe 'with a key that contains special chars (*, _, etc.)' do
|
|
122
|
-
let(:key_with_special_chars) {
|
|
122
|
+
let(:key_with_special_chars) { SPECIAL_CHARACTERS }
|
|
123
123
|
|
|
124
124
|
before do
|
|
125
125
|
ApplicationKey.save(service_id, app_id, key)
|
|
@@ -3,7 +3,7 @@ module ThreeScale
|
|
|
3
3
|
module Core
|
|
4
4
|
describe ApplicationReferrerFilter do
|
|
5
5
|
let(:service_id) { 10 }
|
|
6
|
-
let(:app_id) {
|
|
6
|
+
let(:app_id) { SPECIAL_CHARACTERS }
|
|
7
7
|
let(:filters) { %w(foo bar doopah) }
|
|
8
8
|
let(:application) do
|
|
9
9
|
{ service_id: service_id,
|
|
@@ -24,6 +24,8 @@ module ThreeScale
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
describe '.load_all' do
|
|
27
|
+
subject { ApplicationReferrerFilter.load_all(service_id, app_id) }
|
|
28
|
+
|
|
27
29
|
describe 'Getting all referrer filters' do
|
|
28
30
|
let(:ref_filters) { %w(foo bar) }
|
|
29
31
|
|
|
@@ -32,14 +34,13 @@ module ThreeScale
|
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
it 'returns a sorted list of filters' do
|
|
35
|
-
|
|
36
|
-
filters.must_equal ref_filters.sort
|
|
37
|
+
subject.must_equal ref_filters.sort
|
|
37
38
|
end
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
describe 'when there are no referrer filters' do
|
|
41
42
|
it 'returns an empty list' do
|
|
42
|
-
|
|
43
|
+
subject.must_equal []
|
|
43
44
|
end
|
|
44
45
|
end
|
|
45
46
|
end
|
data/spec/application_spec.rb
CHANGED
|
@@ -47,7 +47,7 @@ module ThreeScale
|
|
|
47
47
|
|
|
48
48
|
describe 'with an app ID that contains special characters' do
|
|
49
49
|
let(:service_id) { 2001 }
|
|
50
|
-
let(:app_id) {
|
|
50
|
+
let(:app_id) { SPECIAL_CHARACTERS }
|
|
51
51
|
|
|
52
52
|
before do
|
|
53
53
|
Application.save service_id: service_id, id: app_id, state: 'suspended',
|
|
@@ -90,7 +90,7 @@ module ThreeScale
|
|
|
90
90
|
|
|
91
91
|
describe 'with an app ID that contains special characters' do
|
|
92
92
|
let(:service_id) { 2001 }
|
|
93
|
-
let(:app_id) {
|
|
93
|
+
let(:app_id) { SPECIAL_CHARACTERS }
|
|
94
94
|
|
|
95
95
|
before do
|
|
96
96
|
Application.save service_id: service_id, id: app_id, state: 'suspended',
|
|
@@ -157,7 +157,7 @@ module ThreeScale
|
|
|
157
157
|
|
|
158
158
|
describe 'with an app ID that contains special characters' do
|
|
159
159
|
let(:service_id) { 2001 }
|
|
160
|
-
let(:app_id) {
|
|
160
|
+
let(:app_id) { SPECIAL_CHARACTERS }
|
|
161
161
|
|
|
162
162
|
before do
|
|
163
163
|
Application.delete(service_id, app_id)
|
|
@@ -269,9 +269,102 @@ module ThreeScale
|
|
|
269
269
|
end
|
|
270
270
|
end
|
|
271
271
|
|
|
272
|
+
describe '.save_batch' do
|
|
273
|
+
let(:service_id) { 2001 }
|
|
274
|
+
|
|
275
|
+
before do
|
|
276
|
+
Application.delete(service_id, 'batch_app_1')
|
|
277
|
+
Application.delete(service_id, 'batch_app_2')
|
|
278
|
+
Application.delete(service_id, 'batch_app_3')
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
it 'creates multiple applications in a single request' do
|
|
282
|
+
apps = [
|
|
283
|
+
{ id: 'batch_app_1', state: 'active', plan_id: '100', plan_name: 'Gold',
|
|
284
|
+
redirect_url: 'http://example.com', user_key: 'uk_batch_1' },
|
|
285
|
+
{ id: 'batch_app_2', state: 'suspended', plan_id: '101', plan_name: 'Silver' }
|
|
286
|
+
]
|
|
287
|
+
|
|
288
|
+
result = Application.save_batch(service_id, apps)
|
|
289
|
+
|
|
290
|
+
result[:status].must_equal 'completed'
|
|
291
|
+
result[:total].must_equal 2
|
|
292
|
+
result[:successful].must_equal 2
|
|
293
|
+
result[:failed].must_equal 0
|
|
294
|
+
|
|
295
|
+
app1 = Application.load(service_id, 'batch_app_1')
|
|
296
|
+
app1.wont_be_nil
|
|
297
|
+
app1.plan_name.must_equal 'Gold'
|
|
298
|
+
|
|
299
|
+
app2 = Application.load(service_id, 'batch_app_2')
|
|
300
|
+
app2.wont_be_nil
|
|
301
|
+
app2.plan_name.must_equal 'Silver'
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
it 'reports failures for invalid applications without blocking valid ones' do
|
|
305
|
+
apps = [
|
|
306
|
+
{ id: 'batch_app_1', state: 'active', plan_id: '100', plan_name: 'Gold' },
|
|
307
|
+
{ id: 'batch_app_3', plan_id: '102', plan_name: 'Bronze' }
|
|
308
|
+
]
|
|
309
|
+
|
|
310
|
+
result = Application.save_batch(service_id, apps)
|
|
311
|
+
|
|
312
|
+
result[:status].must_equal 'completed'
|
|
313
|
+
result[:total].must_equal 2
|
|
314
|
+
result[:successful].must_equal 1
|
|
315
|
+
result[:failed].must_equal 1
|
|
316
|
+
|
|
317
|
+
result[:failures].wont_be_nil
|
|
318
|
+
result[:failures].size.must_equal 1
|
|
319
|
+
result[:failures][0][:id].must_equal 'batch_app_3'
|
|
320
|
+
|
|
321
|
+
Application.load(service_id, 'batch_app_1').wont_be_nil
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it 'returns modified status for existing applications' do
|
|
325
|
+
Application.save(service_id: service_id, id: 'batch_app_1',
|
|
326
|
+
state: 'active', plan_id: '100', plan_name: 'Old')
|
|
327
|
+
|
|
328
|
+
apps = [
|
|
329
|
+
{ id: 'batch_app_1', state: 'active', plan_id: '200', plan_name: 'New' }
|
|
330
|
+
]
|
|
331
|
+
|
|
332
|
+
result = Application.save_batch(service_id, apps)
|
|
333
|
+
|
|
334
|
+
result[:successful].must_equal 1
|
|
335
|
+
result[:applications][0][:status].must_equal 'modified'
|
|
336
|
+
|
|
337
|
+
app = Application.load(service_id, 'batch_app_1')
|
|
338
|
+
app.plan_name.must_equal 'New'
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
it 'handles empty applications array' do
|
|
342
|
+
result = Application.save_batch(service_id, [])
|
|
343
|
+
|
|
344
|
+
result[:status].must_equal 'completed'
|
|
345
|
+
result[:total].must_equal 0
|
|
346
|
+
result[:successful].must_equal 0
|
|
347
|
+
result[:failed].must_equal 0
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
it 'saves user keys and application keys' do
|
|
351
|
+
apps = [
|
|
352
|
+
{ id: 'batch_app_1', state: 'active', plan_id: '100', plan_name: 'Gold',
|
|
353
|
+
user_key: 'uk_batch_test', application_keys: ['ak1', 'ak2'] }
|
|
354
|
+
]
|
|
355
|
+
|
|
356
|
+
result = Application.save_batch(service_id, apps)
|
|
357
|
+
|
|
358
|
+
result[:successful].must_equal 1
|
|
359
|
+
result[:applications][0][:application][:user_key].must_equal 'uk_batch_test'
|
|
360
|
+
result[:applications][0][:application][:application_keys].must_include 'ak1'
|
|
361
|
+
result[:applications][0][:application][:application_keys].must_include 'ak2'
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
272
365
|
describe 'by_key' do
|
|
273
366
|
let(:key) { 'a_key' }
|
|
274
|
-
let(:key_with_special_chars) {
|
|
367
|
+
let(:key_with_special_chars) { SPECIAL_CHARACTERS }
|
|
275
368
|
let(:service_id) { 2001 }
|
|
276
369
|
let(:app_id) { 8011 }
|
|
277
370
|
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
if ENV['COVERAGE'] && !ENV['COVERAGE'].empty?
|
|
2
|
-
require '
|
|
2
|
+
require 'simplecov'
|
|
3
|
+
require 'simplecov_json_formatter'
|
|
3
4
|
SimpleCov.start do
|
|
4
|
-
formatter
|
|
5
|
-
|
|
5
|
+
formatter SimpleCov::Formatter::MultiFormatter.new([
|
|
6
|
+
SimpleCov::Formatter::JSONFormatter,
|
|
6
7
|
SimpleCov::Formatter::HTMLFormatter
|
|
8
|
+
])
|
|
7
9
|
add_filter '/spec/'
|
|
8
10
|
end
|
|
9
11
|
end
|
|
@@ -13,3 +15,5 @@ $:.unshift(File.dirname(__FILE__) + '/../lib')
|
|
|
13
15
|
require 'minitest/autorun'
|
|
14
16
|
require 'bundler/setup'
|
|
15
17
|
Bundler.require(:default, :development, :test)
|
|
18
|
+
|
|
19
|
+
SPECIAL_CHARACTERS = "! \"#$%&'()*+,-.:;<=>?@[]^_`{|}~\\/".freeze
|
data/spec/utilization_spec.rb
CHANGED
|
@@ -105,6 +105,16 @@ module ThreeScale
|
|
|
105
105
|
Utilization.load(service_id, non_existing_app_id).must_be_nil
|
|
106
106
|
end
|
|
107
107
|
end
|
|
108
|
+
|
|
109
|
+
describe 'with an application ID with special characters' do
|
|
110
|
+
let(:app_id) { SPECIAL_CHARACTERS }
|
|
111
|
+
|
|
112
|
+
subject { Utilization.load(service_id, app_id) }
|
|
113
|
+
|
|
114
|
+
it 'gets expected results' do
|
|
115
|
+
subject.wont_be_empty
|
|
116
|
+
end
|
|
117
|
+
end
|
|
108
118
|
end
|
|
109
119
|
end
|
|
110
120
|
end
|
metadata
CHANGED
|
@@ -1,85 +1,96 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pisoni
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.31.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alejandro Martinez Ruiz
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2026-07-03 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: faraday
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '2.0'
|
|
17
19
|
- - ">="
|
|
18
20
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
21
|
+
version: 2.14.3
|
|
20
22
|
type: :runtime
|
|
21
23
|
prerelease: false
|
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
25
|
requirements:
|
|
26
|
+
- - "~>"
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '2.0'
|
|
24
29
|
- - ">="
|
|
25
30
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
31
|
+
version: 2.14.3
|
|
27
32
|
- !ruby/object:Gem::Dependency
|
|
28
33
|
name: json
|
|
29
34
|
requirement: !ruby/object:Gem::Requirement
|
|
30
35
|
requirements:
|
|
36
|
+
- - "~>"
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '2.7'
|
|
31
39
|
- - ">="
|
|
32
40
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
41
|
+
version: 2.7.1
|
|
34
42
|
type: :runtime
|
|
35
43
|
prerelease: false
|
|
36
44
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
45
|
requirements:
|
|
46
|
+
- - "~>"
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '2.7'
|
|
38
49
|
- - ">="
|
|
39
50
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
51
|
+
version: 2.7.1
|
|
41
52
|
- !ruby/object:Gem::Dependency
|
|
42
53
|
name: injectedlogger
|
|
43
54
|
requirement: !ruby/object:Gem::Requirement
|
|
44
55
|
requirements:
|
|
45
|
-
- -
|
|
56
|
+
- - '='
|
|
46
57
|
- !ruby/object:Gem::Version
|
|
47
58
|
version: 0.0.13
|
|
48
59
|
type: :runtime
|
|
49
60
|
prerelease: false
|
|
50
61
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
62
|
requirements:
|
|
52
|
-
- -
|
|
63
|
+
- - '='
|
|
53
64
|
- !ruby/object:Gem::Version
|
|
54
65
|
version: 0.0.13
|
|
55
66
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
67
|
+
name: faraday-net_http_persistent
|
|
57
68
|
requirement: !ruby/object:Gem::Requirement
|
|
58
69
|
requirements:
|
|
59
|
-
- - "
|
|
70
|
+
- - "~>"
|
|
60
71
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '
|
|
72
|
+
version: '2.1'
|
|
62
73
|
type: :runtime
|
|
63
74
|
prerelease: false
|
|
64
75
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
76
|
requirements:
|
|
66
|
-
- - "
|
|
77
|
+
- - "~>"
|
|
67
78
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
79
|
+
version: '2.1'
|
|
69
80
|
- !ruby/object:Gem::Dependency
|
|
70
81
|
name: rake
|
|
71
82
|
requirement: !ruby/object:Gem::Requirement
|
|
72
83
|
requirements:
|
|
73
|
-
- - "
|
|
84
|
+
- - "~>"
|
|
74
85
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
86
|
+
version: '13.1'
|
|
76
87
|
type: :development
|
|
77
88
|
prerelease: false
|
|
78
89
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
90
|
requirements:
|
|
80
|
-
- - "
|
|
91
|
+
- - "~>"
|
|
81
92
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
93
|
+
version: '13.1'
|
|
83
94
|
description: Client for the Apisonator internal API for model data.
|
|
84
95
|
email:
|
|
85
96
|
- alex@3scale.net
|
|
@@ -119,6 +130,7 @@ files:
|
|
|
119
130
|
- lib/3scale_core.rb
|
|
120
131
|
- lib/pisoni.rb
|
|
121
132
|
- pisoni.gemspec
|
|
133
|
+
- podman-compose.yml
|
|
122
134
|
- spec/alert_limit_spec.rb
|
|
123
135
|
- spec/application_key_spec.rb
|
|
124
136
|
- spec/application_referrer_filter_spec.rb
|
|
@@ -137,7 +149,6 @@ homepage: https://github.com/3scale/pisoni
|
|
|
137
149
|
licenses:
|
|
138
150
|
- Apache-2.0
|
|
139
151
|
metadata: {}
|
|
140
|
-
post_install_message:
|
|
141
152
|
rdoc_options:
|
|
142
153
|
- "--charset=UTF-8"
|
|
143
154
|
require_paths:
|
|
@@ -146,15 +157,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
146
157
|
requirements:
|
|
147
158
|
- - ">="
|
|
148
159
|
- !ruby/object:Gem::Version
|
|
149
|
-
version:
|
|
160
|
+
version: 3.0.0
|
|
150
161
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
162
|
requirements:
|
|
152
163
|
- - ">="
|
|
153
164
|
- !ruby/object:Gem::Version
|
|
154
165
|
version: '0'
|
|
155
166
|
requirements: []
|
|
156
|
-
rubygems_version:
|
|
157
|
-
signing_key:
|
|
167
|
+
rubygems_version: 4.0.4
|
|
158
168
|
specification_version: 4
|
|
159
169
|
summary: Client for the Apisonator internal API for model data
|
|
160
170
|
test_files:
|