pact_broker 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|