pact_broker 2.3.0 → 2.4.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 +8 -0
- data/README.md +3 -4
- data/db/migrations/37_create_labels_table.rb +11 -0
- data/lib/pact_broker/api.rb +4 -0
- data/lib/pact_broker/api/decorators/embedded_label_decorator.rb +20 -0
- data/lib/pact_broker/api/decorators/label_decorator.rb +32 -0
- data/lib/pact_broker/api/decorators/pact_collection_decorator.rb +1 -5
- data/lib/pact_broker/api/decorators/pact_versions_decorator.rb +0 -5
- data/lib/pact_broker/api/decorators/pacticipant_collection_decorator.rb +31 -2
- data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +37 -8
- data/lib/pact_broker/api/pact_broker_urls.rb +12 -4
- data/lib/pact_broker/api/resources/label.rb +52 -0
- data/lib/pact_broker/api/resources/pacticipants.rb +1 -1
- data/lib/pact_broker/api/resources/pacticipants_for_label.rb +27 -0
- data/lib/pact_broker/api/resources/verifications.rb +1 -1
- data/lib/pact_broker/badges/service.rb +13 -3
- data/lib/pact_broker/configuration.rb +1 -1
- data/lib/pact_broker/domain.rb +1 -0
- data/lib/pact_broker/domain/label.rb +19 -0
- data/lib/pact_broker/domain/pacticipant.rb +12 -1
- data/lib/pact_broker/labels/repository.rb +32 -0
- data/lib/pact_broker/labels/service.rb +26 -0
- data/lib/pact_broker/pacticipants/repository.rb +8 -7
- data/lib/pact_broker/pacticipants/service.rb +4 -0
- data/lib/pact_broker/repositories.rb +5 -0
- data/lib/pact_broker/services.rb +5 -0
- data/lib/pact_broker/version.rb +1 -1
- data/spec/features/delete_label_spec.rb +28 -0
- data/spec/features/get_label_spec.rb +28 -0
- data/spec/features/get_pacticipants_by_label_spec.rb +27 -0
- data/spec/features/label_pacticipant_spec.rb +22 -0
- data/spec/lib/pact_broker/api/decorators/embedded_label_decorator_spec.rb +34 -0
- data/spec/lib/pact_broker/api/decorators/label_decorator_spec.rb +42 -0
- data/spec/lib/pact_broker/api/decorators/pacticipant_collection_decorator_spec.rb +34 -8
- data/spec/lib/pact_broker/api/decorators/pacticipant_decorator_spec.rb +41 -2
- data/spec/lib/pact_broker/api/decorators/tag_decorator_spec.rb +1 -1
- data/spec/lib/pact_broker/api/resources/verifications_spec.rb +2 -2
- data/spec/lib/pact_broker/badges/service_spec.rb +1 -1
- data/spec/lib/pact_broker/labels/repository_spec.rb +124 -0
- data/spec/lib/pact_broker/labels/service_spec.rb +28 -0
- data/spec/lib/pact_broker/pacticipants/repository_spec.rb +19 -0
- data/spec/support/test_data_builder.rb +6 -0
- data/tasks/database.rb +1 -1
- data/vendor/hal-browser/browser.html +1 -1
- data/vendor/hal-browser/js/hal/resource.js +1 -0
- metadata +26 -2
@@ -11,7 +11,7 @@ module PactBroker
|
|
11
11
|
|
12
12
|
class Configuration
|
13
13
|
|
14
|
-
SAVABLE_SETTING_NAMES = [:order_versions_by_date, :use_case_sensitive_resource_names]
|
14
|
+
SAVABLE_SETTING_NAMES = [:order_versions_by_date, :use_case_sensitive_resource_names, :enable_badge_resources, :shields_io_base_url]
|
15
15
|
|
16
16
|
attr_accessor :log_dir, :database_connection, :auto_migrate_db, :use_hal_browser, :html_pact_renderer
|
17
17
|
attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser
|
data/lib/pact_broker/domain.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'pact_broker/db'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Domain
|
5
|
+
class Label < Sequel::Model
|
6
|
+
|
7
|
+
unrestrict_primary_key
|
8
|
+
|
9
|
+
associate(:many_to_one, :pacticipant, :class => "PactBroker::Domain::Pacticipant", :key => :pacticipant_id, :primary_key => :id)
|
10
|
+
|
11
|
+
def <=> other
|
12
|
+
name <=> other.name
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
Label.plugin :timestamps, update_on_create: true
|
18
|
+
end
|
19
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'pact_broker/db'
|
2
2
|
require 'pact_broker/messages'
|
3
|
+
require 'pact_broker/repositories/helpers'
|
3
4
|
|
4
5
|
module PactBroker
|
5
6
|
|
@@ -12,8 +13,18 @@ module PactBroker
|
|
12
13
|
set_primary_key :id
|
13
14
|
|
14
15
|
one_to_many :versions, :order => :order, :reciprocal => :pacticipant
|
16
|
+
one_to_many :labels, :order => :name, :reciprocal => :pacticipant
|
15
17
|
one_to_many :pacts
|
16
18
|
|
19
|
+
dataset_module do
|
20
|
+
include PactBroker::Repositories::Helpers
|
21
|
+
|
22
|
+
def label label_name
|
23
|
+
filter = name_like(Sequel[:labels][:name], label_name)
|
24
|
+
join(:labels, {pacticipant_id: :id}).where(filter)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
17
28
|
def latest_version
|
18
29
|
versions.last
|
19
30
|
end
|
@@ -29,6 +40,6 @@ module PactBroker
|
|
29
40
|
end
|
30
41
|
end
|
31
42
|
|
32
|
-
Pacticipant.plugin :timestamps, :
|
43
|
+
Pacticipant.plugin :timestamps, update_on_create: true
|
33
44
|
end
|
34
45
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'pact_broker/domain/label'
|
2
|
+
require 'pact_broker/repositories/helpers'
|
3
|
+
|
4
|
+
module PactBroker
|
5
|
+
module Labels
|
6
|
+
class Repository
|
7
|
+
|
8
|
+
include PactBroker::Repositories::Helpers
|
9
|
+
|
10
|
+
def create args
|
11
|
+
Domain::Label.new(name: args.fetch(:name), pacticipant: args.fetch(:pacticipant)).save
|
12
|
+
end
|
13
|
+
|
14
|
+
def find args
|
15
|
+
PactBroker::Domain::Label
|
16
|
+
.select(Sequel.qualify("labels", "name"), Sequel.qualify("labels", "pacticipant_id"), Sequel.qualify("labels", "created_at"), Sequel.qualify("labels", "updated_at"))
|
17
|
+
.join(:pacticipants, {id: :pacticipant_id})
|
18
|
+
.where(name_like(Sequel.qualify("labels", "name"), args.fetch(:label_name)))
|
19
|
+
.where(name_like(Sequel.qualify("pacticipants", "name"), args.fetch(:pacticipant_name)))
|
20
|
+
.single_record
|
21
|
+
end
|
22
|
+
|
23
|
+
def delete args
|
24
|
+
find(args).delete
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete_by_pacticipant_id pacticipant_id
|
28
|
+
Sequel::Model.db[:labels].where(pacticipant_id: pacticipant_id).delete
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'pact_broker/repositories'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
|
5
|
+
module Labels
|
6
|
+
module Service
|
7
|
+
|
8
|
+
extend self
|
9
|
+
|
10
|
+
extend PactBroker::Repositories
|
11
|
+
|
12
|
+
def create args
|
13
|
+
pacticipant = pacticipant_repository.find_by_name_or_create args.fetch(:pacticipant_name)
|
14
|
+
label_repository.create pacticipant: pacticipant, name: args.fetch(:label_name)
|
15
|
+
end
|
16
|
+
|
17
|
+
def find args
|
18
|
+
label_repository.find args
|
19
|
+
end
|
20
|
+
|
21
|
+
def delete args
|
22
|
+
label_repository.delete args
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -17,12 +17,17 @@ module PactBroker
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def find_all
|
20
|
-
|
20
|
+
find
|
21
|
+
end
|
22
|
+
|
23
|
+
def find options = {}
|
24
|
+
query = PactBroker::Domain::Pacticipant.select_all_qualified
|
25
|
+
query = query.label(options[:label_name]) if options[:label_name]
|
26
|
+
query.order_ignore_case(Sequel[:pacticipants][:name]).all
|
21
27
|
end
|
22
28
|
|
23
29
|
def find_all_pacticipant_versions_in_reverse_order name
|
24
|
-
PactBroker::Domain::Version
|
25
|
-
.select(Sequel[:versions][:id], Sequel[:versions][:number], Sequel[:versions][:pacticipant_id], Sequel[:versions][:order], Sequel[:versions][:created_at], Sequel[:versions][:updated_at])
|
30
|
+
PactBroker::Domain::Version.select_all_qualified
|
26
31
|
.join(:pacticipants, {id: :pacticipant_id})
|
27
32
|
.where(name_like(:name, name))
|
28
33
|
.reverse_order(:order)
|
@@ -43,10 +48,6 @@ module PactBroker
|
|
43
48
|
def pacticipant_names
|
44
49
|
PactBroker::Domain::Pacticipant.select(:name).order(:name).collect{ | pacticipant| pacticipant.name }
|
45
50
|
end
|
46
|
-
|
47
|
-
def find_latest_version name
|
48
|
-
|
49
|
-
end
|
50
51
|
end
|
51
52
|
end
|
52
53
|
end
|
@@ -41,6 +41,10 @@ module PactBroker
|
|
41
41
|
pacticipant_repository.find_by_name(name)
|
42
42
|
end
|
43
43
|
|
44
|
+
def self.find options
|
45
|
+
pacticipant_repository.find options
|
46
|
+
end
|
47
|
+
|
44
48
|
def self.find_all_pacticipant_versions_in_reverse_order name
|
45
49
|
pacticipant_repository.find_all_pacticipant_versions_in_reverse_order(name)
|
46
50
|
end
|
@@ -22,6 +22,11 @@ module PactBroker
|
|
22
22
|
Tags::Repository.new
|
23
23
|
end
|
24
24
|
|
25
|
+
def label_repository
|
26
|
+
require 'pact_broker/labels/repository'
|
27
|
+
Labels::Repository.new
|
28
|
+
end
|
29
|
+
|
25
30
|
def webhook_repository
|
26
31
|
require 'pact_broker/webhooks/repository'
|
27
32
|
Webhooks::Repository.new
|
data/lib/pact_broker/services.rb
CHANGED
data/lib/pact_broker/version.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
describe "Deleting a label" do
|
2
|
+
|
3
|
+
before do
|
4
|
+
TestDataBuilder.new
|
5
|
+
.create_pacticipant("foo")
|
6
|
+
.create_label("ios")
|
7
|
+
.create_label("consumer")
|
8
|
+
.create_pacticipant("bar")
|
9
|
+
.create_label("ios")
|
10
|
+
.create_label("consumer")
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:path) { "/pacticipants/foo/labels/ios" }
|
14
|
+
let(:response_body_hash) { JSON.parse(subject.body, symbolize_names: true) }
|
15
|
+
let(:expected_response_body) { {name: 'ios'} }
|
16
|
+
|
17
|
+
subject { delete path; last_response }
|
18
|
+
|
19
|
+
context "when the label exists" do
|
20
|
+
it "returns a 204 No Content" do
|
21
|
+
expect(subject.status).to be 204
|
22
|
+
end
|
23
|
+
|
24
|
+
it "deletes the label" do
|
25
|
+
expect { subject }.to change { PactBroker::Domain::Label.count }.by(-1)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
describe "Get a label" do
|
2
|
+
|
3
|
+
before do
|
4
|
+
TestDataBuilder.new
|
5
|
+
.create_pacticipant("foo")
|
6
|
+
.create_label("ios")
|
7
|
+
.create_label("consumer")
|
8
|
+
.create_pacticipant("bar")
|
9
|
+
.create_label("ios")
|
10
|
+
.create_label("consumer")
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:path) { "/pacticipants/foo/labels/ios" }
|
14
|
+
let(:response_body_hash) { JSON.parse(subject.body, symbolize_names: true) }
|
15
|
+
let(:expected_response_body) { {name: 'ios'} }
|
16
|
+
|
17
|
+
subject { get path; last_response }
|
18
|
+
|
19
|
+
context "when the label exists" do
|
20
|
+
it "returns a 200 OK" do
|
21
|
+
expect(subject).to be_a_hal_json_success_response
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns the label in the body" do
|
25
|
+
expect(response_body_hash).to include expected_response_body
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
describe "Get pacticipants by label" do
|
2
|
+
|
3
|
+
let(:path) { "/pacticipants/label/ios" }
|
4
|
+
let(:response_body_hash) { JSON.parse(subject.body, symbolize_names: true) }
|
5
|
+
let(:expected_response_body) { {name: "Foo"} }
|
6
|
+
|
7
|
+
subject { get path; last_response }
|
8
|
+
|
9
|
+
context "when the pacts exist" do
|
10
|
+
|
11
|
+
before do
|
12
|
+
TestDataBuilder.new
|
13
|
+
.create_pacticipant("Foo")
|
14
|
+
.create_label("ios")
|
15
|
+
.create_pacticipant("Bar")
|
16
|
+
.create_label("android")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns a 200 OK" do
|
20
|
+
expect(subject).to be_a_hal_json_success_response
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns a list of pacticipants" do
|
24
|
+
expect(response_body_hash[:_embedded][:pacticipants].first).to include expected_response_body
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
describe "Labelling a pacticipant" do
|
2
|
+
|
3
|
+
let(:path) { "/pacticipants/foo/labels/ios" }
|
4
|
+
let(:response_body_hash) { JSON.parse(subject.body, symbolize_names: true) }
|
5
|
+
let(:expected_response_body) { {name: 'ios'} }
|
6
|
+
|
7
|
+
subject { put path, nil, {'CONTENT_TYPE' => 'application/json'}; last_response }
|
8
|
+
|
9
|
+
context "when the pacticipant exists" do
|
10
|
+
it "returns a 201 Created" do
|
11
|
+
expect(subject.status).to be 201
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns a json body" do
|
15
|
+
expect(subject.headers['Content-Type']).to eq "application/hal+json;charset=utf-8"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns the label in the body" do
|
19
|
+
expect(response_body_hash).to include expected_response_body
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'pact_broker/api/decorators/embedded_label_decorator'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Api
|
5
|
+
module Decorators
|
6
|
+
|
7
|
+
describe LabelDecorator do
|
8
|
+
|
9
|
+
let(:label) do
|
10
|
+
TestDataBuilder.new
|
11
|
+
.create_consumer("Consumer")
|
12
|
+
.create_label("ios")
|
13
|
+
.and_return(:label)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:options) { { user_options: { base_url: 'http://example.org' } } }
|
17
|
+
|
18
|
+
subject { JSON.parse EmbeddedLabelDecorator.new(label).to_json(options), symbolize_names: true }
|
19
|
+
|
20
|
+
it "includes the label name" do
|
21
|
+
expect(subject[:name]).to eq "ios"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "includes a link to itself" do
|
25
|
+
expect(subject[:_links][:self][:href]).to eq "http://example.org/pacticipants/Consumer/labels/ios"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "includes the label name" do
|
29
|
+
expect(subject[:_links][:self][:name]).to eq "ios"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'pact_broker/api/decorators/label_decorator'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Api
|
5
|
+
module Decorators
|
6
|
+
|
7
|
+
describe LabelDecorator do
|
8
|
+
|
9
|
+
let(:label) do
|
10
|
+
TestDataBuilder.new
|
11
|
+
.create_consumer("Consumer")
|
12
|
+
.create_label("ios")
|
13
|
+
.and_return(:label)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:options) { { user_options: { base_url: 'http://example.org' } } }
|
17
|
+
|
18
|
+
subject { JSON.parse LabelDecorator.new(label).to_json(options), symbolize_names: true }
|
19
|
+
|
20
|
+
it "includes the label name" do
|
21
|
+
expect(subject[:name]).to eq "ios"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "includes a link to itself" do
|
25
|
+
expect(subject[:_links][:self][:href]).to eq "http://example.org/pacticipants/Consumer/labels/ios"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "includes the label name" do
|
29
|
+
expect(subject[:_links][:self][:name]).to eq "ios"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "includes a link to the pacticipant" do
|
33
|
+
expect(subject[:_links][:pacticipant][:href]).to eq "http://example.org/pacticipants/Consumer"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "includes the pacticipant name" do
|
37
|
+
expect(subject[:_links][:pacticipant][:name]).to eq "Consumer"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -3,18 +3,20 @@ require 'pact_broker/api/decorators/pacticipant_collection_decorator'
|
|
3
3
|
require 'pact_broker/domain/pacticipant'
|
4
4
|
|
5
5
|
module PactBroker
|
6
|
-
|
7
6
|
module Api
|
8
|
-
|
9
7
|
module Decorators
|
10
|
-
|
11
8
|
describe PacticipantCollectionDecorator do
|
9
|
+
let(:options) { {user_options: {base_url: 'http://example.org'} } }
|
10
|
+
let(:pacticipants) { [] }
|
11
|
+
let(:json) { PacticipantCollectionDecorator.new(pacticipants).to_json(options) }
|
12
12
|
|
13
|
-
subject { JSON.parse
|
13
|
+
subject { JSON.parse json, symbolize_names: true }
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
it "includes a link to find pacticipants by label" do
|
16
|
+
expect(subject[:_links][:'pb:pacticipants-with-label'][:href]).to match %r{http://.*label/{label}}
|
17
|
+
end
|
17
18
|
|
19
|
+
context "with no pacticipants" do
|
18
20
|
it "doesn't blow up" do
|
19
21
|
subject
|
20
22
|
end
|
@@ -25,11 +27,35 @@ module PactBroker
|
|
25
27
|
let(:pacticipants) { [pacticipant] }
|
26
28
|
|
27
29
|
it "displays a list of pacticipants" do
|
28
|
-
expect(subject[:pacticipants]).to be_instance_of(Array)
|
29
|
-
expect(subject[:pacticipants].size).to eq 1
|
30
|
+
expect(subject[:_embedded][:pacticipants]).to be_instance_of(Array)
|
31
|
+
expect(subject[:_embedded][:pacticipants].size).to eq 1
|
30
32
|
end
|
31
33
|
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe DeprecatedPacticipantCollectionDecorator do
|
37
|
+
let(:options) { {user_options: {base_url: 'http://example.org'} } }
|
38
|
+
let(:pacticipant) { PactBroker::Domain::Pacticipant.new(name: 'Name', created_at: DateTime.new, updated_at: DateTime.new)}
|
39
|
+
let(:pacticipants) { [pacticipant] }
|
40
|
+
let(:json) { DeprecatedPacticipantCollectionDecorator.new(pacticipants).to_json(options) }
|
41
|
+
|
42
|
+
subject { JSON.parse json, symbolize_names: true }
|
43
|
+
|
44
|
+
it "includes the pacticipants under the _embedded key" do
|
45
|
+
expect(subject[:_embedded][:pacticipants]).to be_instance_of(Array)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "includes the pacticipants under the pacticipants key" do
|
49
|
+
expect(subject[:pacticipants]).to be_instance_of(Array)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "includes a deprecation warning in the pacticipants links" do
|
53
|
+
expect(subject[:_links][:pacticipants].first[:name]).to include "DEPRECATED"
|
54
|
+
end
|
32
55
|
|
56
|
+
it "includes a deprecation warning in the non-embedded pacticipant title" do
|
57
|
+
expect(subject[:pacticipants].first[:title]).to include "DEPRECATED"
|
58
|
+
end
|
33
59
|
end
|
34
60
|
end
|
35
61
|
end
|