pact_broker 2.0.0.beta.7 → 2.0.0.beta.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/db/migrations/33_create_config_table.rb +13 -0
- data/example/Gemfile +2 -1
- data/example/config.ru +5 -6
- data/lib/pact_broker/app.rb +12 -3
- data/lib/pact_broker/config/load.rb +57 -0
- data/lib/pact_broker/config/save.rb +84 -0
- data/lib/pact_broker/config/setting.rb +8 -0
- data/lib/pact_broker/configuration.rb +14 -0
- data/lib/pact_broker/pacts/repository.rb +1 -1
- data/lib/pact_broker/ui/view_models/relationship.rb +5 -0
- data/lib/pact_broker/ui/views/relationships/show.haml +11 -3
- data/lib/pact_broker/version.rb +1 -1
- data/lib/rack/pact_broker/add_pact_broker_version_header.rb +23 -0
- data/script/recreate-pg-db.sh +3 -3
- data/spec/features/get_diff_spec.rb +3 -3
- data/spec/features/get_previous_distinct_version.rb +3 -3
- data/spec/lib/pact_broker/app_spec.rb +18 -0
- data/spec/lib/pact_broker/config/load_spec.rb +71 -0
- data/spec/lib/pact_broker/config/save_and_load_spec.rb +25 -0
- data/spec/lib/pact_broker/config/save_spec.rb +83 -0
- data/spec/lib/pact_broker/configuration_spec.rb +35 -1
- data/spec/lib/pact_broker/pacts/diff_spec.rb +3 -3
- data/spec/lib/pact_broker/pacts/repository_spec.rb +4 -4
- data/spec/lib/pact_broker/ui/controllers/relationships_spec.rb +2 -1
- data/spec/lib/pact_broker/versions/repository_spec.rb +1 -1
- data/spec/lib/rack/pact_broker/add_pact_broker_version_header_spec.rb +16 -0
- data/spec/support/provider_state_builder.rb +11 -2
- data/tasks/database.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42dd3a6c7fa5bee17ce117c86063e9c9d2cf4fed
|
4
|
+
data.tar.gz: b7d15c067438b487604aa1ed4a1fe85f43f4ba30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1679dceeb0e560710f3c05a509d56f40c6916927eeb3a0123e25188a38f673753a653afb11b639fd53650846681f346dd534efb84e658087e12fe87419688f36
|
7
|
+
data.tar.gz: 5521914343cbbe71f4d0d6ab977a480fbddf22bbcfce912c20b6271ae46ab09e4a77f0962085ac7c564fc37b6024fa60f636120b7dfcb1895e459fa028d3fe32
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,12 @@ Do this to generate your change history
|
|
2
2
|
|
3
3
|
$ git log --pretty=format:' * %h - %s (%an, %ad)' vX.Y.Z..HEAD
|
4
4
|
|
5
|
+
#### 2.0.0.beta.8 (2017-05-15)
|
6
|
+
* e931b48 - Enable configuration settings to be saved to and loaded from the database. (Beth Skurrie, Mon May 15 12:34:44 2017 +1000)
|
7
|
+
* c3976e4 - Set timezones so dates in the UI and API are shown in the configured local time. (Beth Skurrie, Mon May 15 08:53:13 2017 +1000)
|
8
|
+
* 4da62e8 - Add publication date of latest pact to UI front page. (Beth Skurrie, Sun May 14 08:38:42 2017 +1000)
|
9
|
+
* 8633b08 - Set X-Pact-Broker-Version header in all responses (Beth Skurrie, Fri May 12 16:39:09 2017 +1000)
|
10
|
+
|
5
11
|
#### 2.0.0.beta.7 (2017-05-12)
|
6
12
|
* 741bf96 - Include information about missing verifications in the latest verifications resource. Only set success to be true when all pacts have been successfully verified. (Beth Skurrie, Fri May 12 14:59:48 2017 +1000)
|
7
13
|
* 64f20c6 - Allow one, two or three "parts" in the application version number. Eg. 12, 3.4 and 1.2.400 are all valid. (Beth Skurrie, Wed May 10 16:19:07 2017 +1000)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Sequel.migration do
|
2
|
+
up do
|
3
|
+
create_table(:config, charset: 'utf8') do
|
4
|
+
primary_key :id
|
5
|
+
String :name, null: false
|
6
|
+
String :type, null: false
|
7
|
+
String :value, type: PactBroker::MigrationHelper.large_text_type
|
8
|
+
DateTime :created_at, null: false
|
9
|
+
DateTime :updated_at, null: false
|
10
|
+
index [:name], unique: true, unique_constraint_name: 'unq_config_name'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/example/Gemfile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
3
|
gem 'pact_broker'
|
4
|
-
gem 'sqlite3' #
|
4
|
+
gem 'sqlite3' # Sqlite is just for testing, replace this with your choice of database driver
|
5
|
+
# gem 'pg' # Recommended production gem for postgres
|
5
6
|
gem 'thin' # Keep, or replace with your choice of web server
|
data/example/config.ru
CHANGED
@@ -5,28 +5,27 @@ require 'sequel'
|
|
5
5
|
require 'pact_broker'
|
6
6
|
|
7
7
|
# Create a real database, and set the credentials for it here
|
8
|
-
# It is highly recommended to set the encoding to utf8
|
8
|
+
# It is highly recommended to set the encoding to utf8
|
9
9
|
DATABASE_CREDENTIALS = {adapter: "sqlite", database: "pact_broker_database.sqlite3", :encoding => 'utf8'}
|
10
10
|
|
11
11
|
# For postgres:
|
12
12
|
#
|
13
|
-
# $ psql postgres
|
14
|
-
#
|
15
|
-
# > CREATE USER pact_broker WITH PASSWORD 'pact_broker';
|
16
|
-
# > GRANT ALL PRIVILEGES ON DATABASE pact_broker to pact_broker;
|
13
|
+
# $ psql postgres -c "CREATE DATABASE pact_broker;"
|
14
|
+
# $ psql postgres -c "GRANT ALL PRIVILEGES ON DATABASE pact_broker TO pact_broker;"
|
17
15
|
#
|
18
16
|
# DATABASE_CREDENTIALS = {adapter: "postgres", database: "pact_broker", username: 'pact_broker', password: 'pact_broker', :encoding => 'utf8'}
|
19
17
|
|
20
18
|
# Have a look at the Sequel documentation to make decisions about things like connection pooling
|
21
19
|
# and connection validation.
|
22
20
|
|
21
|
+
ENV['TZ'] = 'Australia/Melbourne' # Set the timezone you want your dates to appear in
|
22
|
+
|
23
23
|
app = PactBroker::App.new do | config |
|
24
24
|
# change these from their default values if desired
|
25
25
|
# config.log_dir = "./log"
|
26
26
|
# config.auto_migrate_db = true
|
27
27
|
# config.use_hal_browser = true
|
28
28
|
config.database_connection = Sequel.connect(DATABASE_CREDENTIALS.merge(:logger => config.logger))
|
29
|
-
config.database_connection.timezone = :utc
|
30
29
|
end
|
31
30
|
|
32
31
|
run app
|
data/lib/pact_broker/app.rb
CHANGED
@@ -2,6 +2,7 @@ require 'pact_broker/configuration'
|
|
2
2
|
require 'pact_broker/db'
|
3
3
|
require 'pact_broker/project_root'
|
4
4
|
require 'rack/hal_browser'
|
5
|
+
require 'rack/pact_broker/add_pact_broker_version_header'
|
5
6
|
require 'rack/pact_broker/convert_file_extension_to_accept_header'
|
6
7
|
require 'sucker_punch'
|
7
8
|
|
@@ -30,10 +31,8 @@ module PactBroker
|
|
30
31
|
|
31
32
|
def post_configure
|
32
33
|
PactBroker.logger = configuration.logger
|
33
|
-
PactBroker::DB.connection = configuration.database_connection
|
34
|
-
PactBroker::DB.connection.timezone = :utc
|
35
|
-
PactBroker::DB.validate_connection_config if configuration.validate_database_connection_config
|
36
34
|
SuckerPunch.logger = configuration.logger
|
35
|
+
configure_database_connection
|
37
36
|
|
38
37
|
if configuration.auto_migrate_db
|
39
38
|
logger.info "Migrating database"
|
@@ -43,9 +42,19 @@ module PactBroker
|
|
43
42
|
end
|
44
43
|
end
|
45
44
|
|
45
|
+
def configure_database_connection
|
46
|
+
PactBroker::DB.connection = configuration.database_connection
|
47
|
+
PactBroker::DB.connection.timezone = :utc
|
48
|
+
PactBroker::DB.validate_connection_config if configuration.validate_database_connection_config
|
49
|
+
Sequel.database_timezone = :utc # Store all dates in UTC, assume any date without a TZ is UTC
|
50
|
+
Sequel.application_timezone = :local # Convert dates to localtime when retrieving from database
|
51
|
+
Sequel.typecast_timezone = :utc # If no timezone specified on dates going into the database, assume they are UTC
|
52
|
+
end
|
53
|
+
|
46
54
|
def build_app
|
47
55
|
@app = Rack::Builder.new
|
48
56
|
|
57
|
+
@app.use Rack::PactBroker::AddPactBrokerVersionHeader
|
49
58
|
@app.use Rack::Static, :urls => ["/stylesheets", "/css", "/fonts", "/js", "/javascripts", "/images"], :root => PactBroker.project_root.join("public")
|
50
59
|
@app.use Rack::PactBroker::ConvertFileExtensionToAcceptHeader
|
51
60
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'pact_broker/configuration'
|
2
|
+
require 'pact_broker/logging'
|
3
|
+
require 'pact_broker/config/setting'
|
4
|
+
|
5
|
+
module PactBroker
|
6
|
+
module Config
|
7
|
+
class Load
|
8
|
+
|
9
|
+
include PactBroker::Logging
|
10
|
+
|
11
|
+
def self.call configuration
|
12
|
+
new(configuration).call
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize configuration
|
16
|
+
@configuration = configuration
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
Setting.each do | setting |
|
21
|
+
set_value_on_configuration setting
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
attr_reader :configuration
|
28
|
+
|
29
|
+
def configuration_attribute_exists? setting
|
30
|
+
configuration.respond_to?("#{setting.name}=")
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_value_on_configuration setting
|
34
|
+
if configuration_attribute_exists? setting
|
35
|
+
configuration.send("#{setting.name}=", get_value_from_setting(setting))
|
36
|
+
else
|
37
|
+
logger.warn("Could not load configuration setting \"#{setting.name}\" as there is no matching attribute on the Configuration class")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_value_from_setting setting
|
42
|
+
case setting.type
|
43
|
+
when 'json'
|
44
|
+
JSON.parse(setting.value, symbolize_names: true)
|
45
|
+
when 'string'
|
46
|
+
setting.value
|
47
|
+
when 'integer'
|
48
|
+
Integer(setting.value)
|
49
|
+
when 'float'
|
50
|
+
Float(setting.value)
|
51
|
+
when 'boolean'
|
52
|
+
setting.value == "1"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'pact_broker/configuration'
|
2
|
+
require 'pact_broker/logging'
|
3
|
+
require 'pact_broker/config/setting'
|
4
|
+
|
5
|
+
module PactBroker
|
6
|
+
module Config
|
7
|
+
class Save
|
8
|
+
|
9
|
+
include PactBroker::Logging
|
10
|
+
|
11
|
+
def self.call configuration, setting_names
|
12
|
+
new(configuration, setting_names).call
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize configuration, setting_names
|
16
|
+
@configuration = configuration
|
17
|
+
@setting_names = setting_names
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
setting_names.each do | setting_name |
|
22
|
+
if class_supported?(setting_name)
|
23
|
+
create_or_update_setting(setting_name)
|
24
|
+
else
|
25
|
+
logger.warn "Could not save configuration setting \"#{setting_name}\" to database as the class #{get_value(setting_name).class} is not supported."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :configuration, :setting_names
|
33
|
+
|
34
|
+
def create_or_update_setting setting_name
|
35
|
+
setting = Setting.find(name: setting_name.to_s) || Setting.new(name: setting_name.to_s)
|
36
|
+
setting.type = get_db_type(setting_name)
|
37
|
+
setting.value = get_db_value(setting_name)
|
38
|
+
setting.save
|
39
|
+
end
|
40
|
+
|
41
|
+
def class_supported? setting_name
|
42
|
+
!!get_db_type(setting_name)
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_db_type setting_name
|
46
|
+
val = get_value(setting_name)
|
47
|
+
case val
|
48
|
+
when true, false
|
49
|
+
'boolean'
|
50
|
+
when String, nil
|
51
|
+
'string'
|
52
|
+
when Array, Hash
|
53
|
+
'json'
|
54
|
+
when Integer
|
55
|
+
'integer'
|
56
|
+
when Float
|
57
|
+
'float'
|
58
|
+
else
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def get_db_value setting_name
|
64
|
+
val = get_value(setting_name)
|
65
|
+
case val
|
66
|
+
when String, Integer, Float, NilClass
|
67
|
+
val
|
68
|
+
when TrueClass
|
69
|
+
"1"
|
70
|
+
when FalseClass
|
71
|
+
"0"
|
72
|
+
when Array, Hash
|
73
|
+
val.to_json
|
74
|
+
else
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_value setting_name
|
80
|
+
configuration.send(setting_name)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -6,6 +6,8 @@ module PactBroker
|
|
6
6
|
|
7
7
|
class Configuration
|
8
8
|
|
9
|
+
SAVABLE_SETTING_NAMES = [:order_versions_by_date, :use_case_sensitive_resource_names]
|
10
|
+
|
9
11
|
attr_accessor :log_dir, :database_connection, :auto_migrate_db, :use_hal_browser, :html_pact_renderer
|
10
12
|
attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser
|
11
13
|
attr_accessor :use_case_sensitive_resource_names, :order_versions_by_date
|
@@ -41,6 +43,18 @@ module PactBroker
|
|
41
43
|
}
|
42
44
|
end
|
43
45
|
|
46
|
+
def save_to_database
|
47
|
+
# Can't require a Sequel::Model class before the connection has been set
|
48
|
+
require 'pact_broker/config/save'
|
49
|
+
PactBroker::Config::Save.call(self, SAVABLE_SETTING_NAMES)
|
50
|
+
end
|
51
|
+
|
52
|
+
def load_from_database!
|
53
|
+
# Can't require a Sequel::Model class before the connection has been set
|
54
|
+
require 'pact_broker/config/load'
|
55
|
+
PactBroker::Config::Load.call(self)
|
56
|
+
end
|
57
|
+
|
44
58
|
private
|
45
59
|
|
46
60
|
def create_logger path
|
@@ -60,7 +60,7 @@ module PactBroker
|
|
60
60
|
|
61
61
|
def find_latest_pact_versions_for_provider provider_name, tag = nil
|
62
62
|
if tag
|
63
|
-
LatestTaggedPactPublications.provider(provider_name).where(tag_name: tag).order(:consumer_name).collect(&:to_domain)
|
63
|
+
LatestTaggedPactPublications.provider(provider_name).order(:consumer_name).where(tag_name: tag).order(:consumer_name).collect(&:to_domain)
|
64
64
|
else
|
65
65
|
LatestPactPublications.provider(provider_name).order(:consumer_name).collect(&:to_domain)
|
66
66
|
end
|
@@ -42,6 +42,11 @@ module PactBroker
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
def publication_date_of_latest_pact
|
46
|
+
date = @relationship.latest_pact.created_at
|
47
|
+
PactBroker::DateHelper.distance_of_time_in_words(date, DateTime.now) + " ago"
|
48
|
+
end
|
49
|
+
|
45
50
|
def verification_status
|
46
51
|
return "" unless @relationship.ever_verified?
|
47
52
|
if @relationship.latest_verification_successful?
|
@@ -28,6 +28,8 @@
|
|
28
28
|
Provider
|
29
29
|
%span.glyphicon.glyphicon-sort.relationships-sort
|
30
30
|
%th
|
31
|
+
%th
|
32
|
+
Latest pact published
|
31
33
|
%th
|
32
34
|
Last verified
|
33
35
|
%tbody
|
@@ -45,8 +47,10 @@
|
|
45
47
|
%a{:href => relationship.provider_group_url}
|
46
48
|
= relationship.provider_name
|
47
49
|
%td
|
48
|
-
%td
|
49
|
-
|
50
|
+
%td
|
51
|
+
= relationship.publication_date_of_latest_pact
|
52
|
+
%td{class: relationship.verification_status, title: relationship.verification_tooltip, "data-toggle": "tooltip", "data-placement": "left"}
|
53
|
+
%div
|
50
54
|
= relationship.last_verified_date
|
51
55
|
- if relationship.warning?
|
52
56
|
%span.glyphicon.glyphicon-warning-sign{'aria-hidden':true}
|
@@ -60,5 +64,9 @@
|
|
60
64
|
|
61
65
|
$(document).ready(function(){
|
62
66
|
$("span.pact").load("/images/doc-text.svg");
|
63
|
-
$('[data-toggle="tooltip"]').
|
67
|
+
$('td[data-toggle="tooltip"]').each(function(index, td){
|
68
|
+
//appended tooltip div screws up table if it's appended after a
|
69
|
+
//td, so need to append it to a div
|
70
|
+
$(td).tooltip({container: $(td).first()});
|
71
|
+
});
|
64
72
|
});
|
data/lib/pact_broker/version.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'pact_broker/version'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module PactBroker
|
5
|
+
class AddPactBrokerVersionHeader
|
6
|
+
|
7
|
+
X_PACT_BROKER_VERSION = 'X-Pact-Broker-Version'.freeze
|
8
|
+
|
9
|
+
def initialize app
|
10
|
+
@app = app
|
11
|
+
end
|
12
|
+
|
13
|
+
def call env
|
14
|
+
response = @app.call(env)
|
15
|
+
[response[0], add_version_header(response[1]), response[2]]
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_version_header headers
|
19
|
+
headers.merge(X_PACT_BROKER_VERSION => ::PactBroker::VERSION)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/script/recreate-pg-db.sh
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
psql postgres -c "
|
2
|
-
psql postgres -c "
|
3
|
-
psql postgres -c "GRANT ALL PRIVILEGES ON DATABASE pact_broker
|
1
|
+
psql postgres -c "DROP DATABASE pact_broker;"
|
2
|
+
psql postgres -c "CREATE DATABASE pact_broker;"
|
3
|
+
psql postgres -c "GRANT ALL PRIVILEGES ON DATABASE pact_broker TO pact_broker;"
|
4
4
|
ip=$(ifconfig en0 | sed -n -e '/inet/s/.*inet \([0-9.]*\) netmask .*/\1/p')
|
5
5
|
echo ""
|
6
6
|
echo "run the following command to set your environment variables:"
|
@@ -21,11 +21,11 @@ describe "Get diff between versions" do
|
|
21
21
|
.create_consumer("Consumer")
|
22
22
|
.create_provider("Provider")
|
23
23
|
.create_consumer_version("1")
|
24
|
-
.create_pact(pact_content_version_1)
|
24
|
+
.create_pact(json_content: pact_content_version_1)
|
25
25
|
.create_consumer_version("2")
|
26
|
-
.create_pact(pact_content_version_2)
|
26
|
+
.create_pact(json_content: pact_content_version_2)
|
27
27
|
.create_consumer_version("3")
|
28
|
-
.create_pact(pact_content_version_3)
|
28
|
+
.create_pact(json_content: pact_content_version_3)
|
29
29
|
end
|
30
30
|
|
31
31
|
context "when the versions exist" do
|
@@ -20,11 +20,11 @@ describe "Get previous distinct version of pact" do
|
|
20
20
|
.create_consumer("Consumer")
|
21
21
|
.create_provider("Provider")
|
22
22
|
.create_consumer_version("1")
|
23
|
-
.create_pact(pact_content_version_1)
|
23
|
+
.create_pact(json_content: pact_content_version_1)
|
24
24
|
.create_consumer_version("2")
|
25
|
-
.create_pact(pact_content_version_2)
|
25
|
+
.create_pact(json_content: pact_content_version_2)
|
26
26
|
.create_consumer_version("3")
|
27
|
-
.create_pact(pact_content_version_3)
|
27
|
+
.create_pact(json_content: pact_content_version_3)
|
28
28
|
end
|
29
29
|
|
30
30
|
context "when the pact version exists" do
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'pact_broker/app'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
describe App do
|
5
|
+
|
6
|
+
let(:app) do
|
7
|
+
PactBroker::App.new do | configuration |
|
8
|
+
configuration.database_connection = PactBroker::DB.connection
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
it "adds the X-Pact-Broker-Version header" do
|
13
|
+
get "/"
|
14
|
+
expect(last_response.headers['X-Pact-Broker-Version']).to match /\d/
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'pact_broker/config/load'
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Config
|
5
|
+
describe Load do
|
6
|
+
|
7
|
+
describe ".call" do
|
8
|
+
|
9
|
+
class MockConfig
|
10
|
+
attr_accessor :foo, :bar, :nana, :meep, :lalala, :meow, :peebo
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
Setting.create(name: 'foo', type: 'json', value: {"a" => "thing"}.to_json)
|
15
|
+
Setting.create(name: 'bar', type: 'string', value: "bar")
|
16
|
+
Setting.create(name: 'nana', type: 'integer', value: "1")
|
17
|
+
Setting.create(name: 'meep', type: 'float', value: "1.2")
|
18
|
+
Setting.create(name: 'lalala', type: 'boolean', value: "1")
|
19
|
+
Setting.create(name: 'meow', type: 'boolean', value: "0")
|
20
|
+
Setting.create(name: 'peebo', type: 'string', value: nil)
|
21
|
+
Setting.create(name: 'unknown', type: 'string', value: nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:configuration) { MockConfig.new }
|
25
|
+
|
26
|
+
subject { Load.call(configuration) }
|
27
|
+
|
28
|
+
it "loads a JSON config" do
|
29
|
+
subject
|
30
|
+
expect(configuration.foo).to eq(a: "thing")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "loads a String setting" do
|
34
|
+
subject
|
35
|
+
expect(configuration.bar).to eq "bar"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "loads an Integer setting" do
|
39
|
+
subject
|
40
|
+
expect(configuration.nana).to eq 1
|
41
|
+
end
|
42
|
+
|
43
|
+
it "loads a Float setting" do
|
44
|
+
subject
|
45
|
+
expect(configuration.meep).to eq 1.2
|
46
|
+
end
|
47
|
+
|
48
|
+
it "loads a true setting" do
|
49
|
+
subject
|
50
|
+
expect(configuration.lalala).to eq true
|
51
|
+
end
|
52
|
+
|
53
|
+
it "loads a false setting" do
|
54
|
+
subject
|
55
|
+
expect(configuration.meow).to eq false
|
56
|
+
end
|
57
|
+
|
58
|
+
it "loads a nil setting" do
|
59
|
+
subject
|
60
|
+
expect(configuration.peebo).to eq nil
|
61
|
+
end
|
62
|
+
|
63
|
+
it "does not load a setting where the Configuration object does not have a matching property" do
|
64
|
+
allow(Load.logger).to receive(:warn)
|
65
|
+
expect(Load.logger).to receive(:warn).with("Could not load configuration setting \"unknown\" as there is no matching attribute on the Configuration class")
|
66
|
+
subject
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'pact_broker/config/load'
|
2
|
+
require 'pact_broker/config/save'
|
3
|
+
|
4
|
+
module PactBroker
|
5
|
+
module Config
|
6
|
+
describe "Save and Load" do
|
7
|
+
|
8
|
+
let(:setting_names) { configuration_to_save.to_h.keys }
|
9
|
+
let(:configuration_to_save) do
|
10
|
+
OpenStruct.new(foo: true, bar: false, wiffle: nil, meep: [1, "2"], mop: {a: "b"}, la: 1, lala: 1.2)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:loaded_configuration) do
|
14
|
+
OpenStruct.new(foo: nil, bar: "1", wiffle: [], meep: nil, mop: nil, la: nil, lala: nil)
|
15
|
+
end
|
16
|
+
|
17
|
+
subject { Save.call(configuration_to_save, setting_names); Load.call(loaded_configuration) }
|
18
|
+
|
19
|
+
it "the loaded configuration is the same as the saved one" do
|
20
|
+
subject
|
21
|
+
expect(loaded_configuration).to eq configuration_to_save
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'pact_broker/config/save'
|
2
|
+
require 'pact_broker/configuration'
|
3
|
+
|
4
|
+
module PactBroker
|
5
|
+
module Config
|
6
|
+
describe Save do
|
7
|
+
|
8
|
+
describe "#call" do
|
9
|
+
let(:setting_names) { [:foo, :bar, :wiffle, :meep, :flop, :peebo, :lalala, :meow] }
|
10
|
+
let(:configuration) do
|
11
|
+
double("PactBroker::Configuration",
|
12
|
+
foo: true,
|
13
|
+
bar: false,
|
14
|
+
wiffle: ["a", "b", "c"],
|
15
|
+
meep: {a: 'thing'},
|
16
|
+
flop: nil,
|
17
|
+
peebo: 1,
|
18
|
+
lalala: 1.2,
|
19
|
+
meow: Object.new)
|
20
|
+
end
|
21
|
+
|
22
|
+
subject { Save.call(configuration, setting_names) }
|
23
|
+
|
24
|
+
it "saves a false config setting to the database" do
|
25
|
+
subject
|
26
|
+
setting = Setting.find(name: 'foo')
|
27
|
+
expect(setting.type).to eq 'boolean'
|
28
|
+
expect(setting.value).to eq '1'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "saves a true config setting to the database" do
|
32
|
+
subject
|
33
|
+
setting = Setting.find(name: 'bar')
|
34
|
+
expect(setting.type).to eq 'boolean'
|
35
|
+
expect(setting.value).to eq '0'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "saves an array to the database" do
|
39
|
+
subject
|
40
|
+
setting = Setting.find(name: 'wiffle')
|
41
|
+
expect(setting.type).to eq 'json'
|
42
|
+
expect(setting.value).to eq '["a","b","c"]'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "saves a hash to the database" do
|
46
|
+
subject
|
47
|
+
setting = Setting.find(name: 'meep')
|
48
|
+
expect(setting.type).to eq 'json'
|
49
|
+
expect(setting.value).to eq "{\"a\":\"thing\"}"
|
50
|
+
end
|
51
|
+
|
52
|
+
it "saves a nil to the database" do
|
53
|
+
subject
|
54
|
+
setting = Setting.find(name: 'flop')
|
55
|
+
expect(setting.type).to eq 'string'
|
56
|
+
expect(setting.value).to eq nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it "saves an Integer to the database" do
|
60
|
+
subject
|
61
|
+
setting = Setting.find(name: 'peebo')
|
62
|
+
expect(setting.type).to eq 'integer'
|
63
|
+
expect(setting.value).to eq '1'
|
64
|
+
end
|
65
|
+
|
66
|
+
it "saves a Float to the database" do
|
67
|
+
subject
|
68
|
+
setting = Setting.find(name: 'lalala')
|
69
|
+
expect(setting.type).to eq 'float'
|
70
|
+
expect(setting.value).to eq '1.2'
|
71
|
+
end
|
72
|
+
|
73
|
+
it "does not save an arbitrary object to the database" do
|
74
|
+
allow(Save.logger).to receive(:warn)
|
75
|
+
expect(Save.logger).to receive(:warn).with("Could not save configuration setting \"meow\" to database as the class Object is not supported.")
|
76
|
+
subject
|
77
|
+
setting = Setting.find(name: 'meow')
|
78
|
+
expect(setting).to be nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'pact_broker/configuration'
|
3
3
|
require 'pact_broker/api/renderers/html_pact_renderer'
|
4
|
+
require 'pact_broker/config/setting'
|
4
5
|
|
5
6
|
module PactBroker
|
6
7
|
describe Configuration do
|
@@ -16,6 +17,39 @@ module PactBroker
|
|
16
17
|
end
|
17
18
|
|
18
19
|
end
|
20
|
+
|
21
|
+
describe "SETTING_NAMES" do
|
22
|
+
let(:configuration) { PactBroker::Configuration.new}
|
23
|
+
|
24
|
+
Configuration::SAVABLE_SETTING_NAMES.each do | setting_name |
|
25
|
+
describe setting_name do
|
26
|
+
it "exists as a method on a PactBroker::Configuration instance" do
|
27
|
+
expect(configuration).to respond_to(setting_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "save_to_database" do
|
34
|
+
let(:configuration) { PactBroker::Configuration.default_configuration }
|
35
|
+
|
36
|
+
it "saves the configuration to the database" do
|
37
|
+
expect { configuration.save_to_database }.to change { PactBroker::Config::Setting.count }.by(Configuration::SAVABLE_SETTING_NAMES.size)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "load_from_database!" do
|
42
|
+
let(:configuration) { PactBroker::Configuration.new}
|
43
|
+
|
44
|
+
before do
|
45
|
+
PactBroker::Config::Setting.create(name: 'use_case_sensitive_resource_names', type: 'string', value: 'foo')
|
46
|
+
end
|
47
|
+
|
48
|
+
it "loads the configurations from the database" do
|
49
|
+
configuration.load_from_database!
|
50
|
+
expect(configuration.use_case_sensitive_resource_names).to eq "foo"
|
51
|
+
end
|
52
|
+
end
|
19
53
|
end
|
20
54
|
end
|
21
|
-
end
|
55
|
+
end
|
@@ -21,11 +21,11 @@ module PactBroker
|
|
21
21
|
.create_consumer("Consumer")
|
22
22
|
.create_provider("Provider")
|
23
23
|
.create_consumer_version("1")
|
24
|
-
.create_pact(pact_content_version_1)
|
24
|
+
.create_pact(json_content: pact_content_version_1)
|
25
25
|
.create_consumer_version("2")
|
26
|
-
.create_pact(pact_content_version_2)
|
26
|
+
.create_pact(json_content: pact_content_version_2)
|
27
27
|
.create_consumer_version("3")
|
28
|
-
.create_pact(pact_content_version_3)
|
28
|
+
.create_pact(json_content: pact_content_version_3)
|
29
29
|
allow(DateHelper).to receive(:local_date_in_words).and_return("a date")
|
30
30
|
end
|
31
31
|
|
@@ -416,13 +416,13 @@ module PactBroker
|
|
416
416
|
.create_consumer("Consumer")
|
417
417
|
.create_provider("Provider")
|
418
418
|
.create_consumer_version("1")
|
419
|
-
.create_pact(pact_content_version_1)
|
419
|
+
.create_pact(json_content: pact_content_version_1)
|
420
420
|
.create_consumer_version("2")
|
421
|
-
.create_pact(pact_content_version_2)
|
421
|
+
.create_pact(json_content: pact_content_version_2)
|
422
422
|
.create_consumer_version("3")
|
423
|
-
.create_pact(pact_content_version_3)
|
423
|
+
.create_pact(json_content: pact_content_version_3)
|
424
424
|
.create_consumer_version("4")
|
425
|
-
.create_pact(pact_content_version_4)
|
425
|
+
.create_pact(json_content: pact_content_version_4)
|
426
426
|
expect(pact_content_version_3).to_not eq pact_content_version_4
|
427
427
|
end
|
428
428
|
|
@@ -17,7 +17,8 @@ module PactBroker
|
|
17
17
|
|
18
18
|
let(:consumer) { instance_double("PactBroker::Domain::Pacticipant", name: 'consumer_name')}
|
19
19
|
let(:provider) { instance_double("PactBroker::Domain::Pacticipant", name: 'provider_name')}
|
20
|
-
let(:
|
20
|
+
let(:pact) { instance_double("PactBroker::Domain::Pact", created_at: Date.new(2017))}
|
21
|
+
let(:relationship) { PactBroker::Domain::Relationship.new(consumer, provider, pact)}
|
21
22
|
let(:relationships) { [relationship] }
|
22
23
|
|
23
24
|
before do
|
@@ -41,7 +41,7 @@ module PactBroker
|
|
41
41
|
end
|
42
42
|
|
43
43
|
it "returns the version" do
|
44
|
-
expect(subject.id).to_not
|
44
|
+
expect(subject.id).to_not be nil
|
45
45
|
expect(subject.number).to eq version_number
|
46
46
|
expect(subject.pacticipant.name).to eq pacticipant_name
|
47
47
|
expect(subject.tags.first.name).to eq "prod"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rack/pact_broker/add_pact_broker_version_header'
|
2
|
+
|
3
|
+
module Rack
|
4
|
+
module PactBroker
|
5
|
+
describe AddPactBrokerVersionHeader do
|
6
|
+
|
7
|
+
let(:app) { AddPactBrokerVersionHeader.new(->(env){[200, {}, []]}) }
|
8
|
+
|
9
|
+
it "adds the PactBroker version as a header" do
|
10
|
+
get "/"
|
11
|
+
expect(last_response.headers['X-Pact-Broker-Version']).to match /\d/
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -133,8 +133,11 @@ class ProviderStateBuilder
|
|
133
133
|
self
|
134
134
|
end
|
135
135
|
|
136
|
-
def create_pact
|
137
|
-
@pact = PactBroker::Pacts::Repository.new.create(version_id: @consumer_version.id, consumer_id: @consumer.id, provider_id: @provider.id, json_content: json_content)
|
136
|
+
def create_pact params = {}
|
137
|
+
@pact = PactBroker::Pacts::Repository.new.create({version_id: @consumer_version.id, consumer_id: @consumer.id, provider_id: @provider.id, json_content: params[:json_content] || default_json_content})
|
138
|
+
set_created_at_if_set params[:created_at], :pact_publications, {id: @pact.id}
|
139
|
+
set_created_at_if_set params[:created_at], :pact_versions, {sha: @pact.pact_version_sha}
|
140
|
+
@pact = PactBroker::Pacts::PactPublication.find(id: @pact.id).to_domain
|
138
141
|
self
|
139
142
|
end
|
140
143
|
|
@@ -170,6 +173,12 @@ class ProviderStateBuilder
|
|
170
173
|
|
171
174
|
private
|
172
175
|
|
176
|
+
def set_created_at_if_set created_at, table_name, selector
|
177
|
+
if created_at
|
178
|
+
Sequel::Model.db.run("update #{table_name} set created_at = \"#{created_at.xmlschema}\" where #{selector.keys.first} = \"#{selector.values.first}\"")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
173
182
|
def default_json_content
|
174
183
|
{
|
175
184
|
"consumer" => {
|
data/tasks/database.rb
CHANGED
@@ -8,7 +8,7 @@ Sequel.extension :migration
|
|
8
8
|
module PactBroker
|
9
9
|
module Database
|
10
10
|
|
11
|
-
TABLES = [:pacts, :pact_version_contents, :tags, :verifications, :pact_publications, :pact_versions, :webhook_headers, :webhooks, :versions, :pacticipants].freeze
|
11
|
+
TABLES = [:config, :pacts, :pact_version_contents, :tags, :verifications, :pact_publications, :pact_versions, :webhook_headers, :webhooks, :versions, :pacticipants].freeze
|
12
12
|
|
13
13
|
extend self
|
14
14
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pact_broker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.beta.
|
4
|
+
version: 2.0.0.beta.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bethany Skurrie
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-05-
|
13
|
+
date: 2017-05-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: httparty
|
@@ -431,6 +431,7 @@ files:
|
|
431
431
|
- db/migrations/30_drop_old_tables_and_views.rb
|
432
432
|
- db/migrations/31_create_verifications.rb
|
433
433
|
- db/migrations/32_create_latest_verifications.rb
|
434
|
+
- db/migrations/33_create_config_table.rb
|
434
435
|
- db/migrations/migration_helper.rb
|
435
436
|
- db/pact_broker_database.sqlite3
|
436
437
|
- example/Gemfile
|
@@ -506,6 +507,9 @@ files:
|
|
506
507
|
- lib/pact_broker/api/resources/webhook_resource_methods.rb
|
507
508
|
- lib/pact_broker/api/resources/webhooks.rb
|
508
509
|
- lib/pact_broker/app.rb
|
510
|
+
- lib/pact_broker/config/load.rb
|
511
|
+
- lib/pact_broker/config/save.rb
|
512
|
+
- lib/pact_broker/config/setting.rb
|
509
513
|
- lib/pact_broker/configuration.rb
|
510
514
|
- lib/pact_broker/constants.rb
|
511
515
|
- lib/pact_broker/date_helper.rb
|
@@ -601,6 +605,7 @@ files:
|
|
601
605
|
- lib/pact_broker/webhooks/webhook.rb
|
602
606
|
- lib/rack/hal_browser.rb
|
603
607
|
- lib/rack/hal_browser/redirect.rb
|
608
|
+
- lib/rack/pact_broker/add_pact_broker_version_header.rb
|
604
609
|
- lib/rack/pact_broker/convert_file_extension_to_accept_header.rb
|
605
610
|
- pact_broker.gemspec
|
606
611
|
- pact_broker_client-pact_broker.json
|
@@ -699,6 +704,10 @@ files:
|
|
699
704
|
- spec/lib/pact_broker/api/resources/webhook_execution_spec.rb
|
700
705
|
- spec/lib/pact_broker/api/resources/webhook_spec.rb
|
701
706
|
- spec/lib/pact_broker/api/resources/webhooks_spec.rb
|
707
|
+
- spec/lib/pact_broker/app_spec.rb
|
708
|
+
- spec/lib/pact_broker/config/load_spec.rb
|
709
|
+
- spec/lib/pact_broker/config/save_and_load_spec.rb
|
710
|
+
- spec/lib/pact_broker/config/save_spec.rb
|
702
711
|
- spec/lib/pact_broker/configuration_spec.rb
|
703
712
|
- spec/lib/pact_broker/db/validate_encoding_spec.rb
|
704
713
|
- spec/lib/pact_broker/diagnostic/resources/dependencies_spec.rb
|
@@ -739,6 +748,7 @@ files:
|
|
739
748
|
- spec/lib/pact_broker/webhooks/repository_spec.rb
|
740
749
|
- spec/lib/pact_broker/webhooks/service_spec.rb
|
741
750
|
- spec/lib/rack/hal_browser/redirect_spec.rb
|
751
|
+
- spec/lib/rack/pact_broker/add_pact_broker_version_header_spec.rb
|
742
752
|
- spec/migrations/23_pact_versions_spec.rb
|
743
753
|
- spec/migrations/24_populate_pact_contents_spec.rb
|
744
754
|
- spec/migrations/34_latest_tagged_pacts_spec.rb
|
@@ -881,6 +891,10 @@ test_files:
|
|
881
891
|
- spec/lib/pact_broker/api/resources/webhook_execution_spec.rb
|
882
892
|
- spec/lib/pact_broker/api/resources/webhook_spec.rb
|
883
893
|
- spec/lib/pact_broker/api/resources/webhooks_spec.rb
|
894
|
+
- spec/lib/pact_broker/app_spec.rb
|
895
|
+
- spec/lib/pact_broker/config/load_spec.rb
|
896
|
+
- spec/lib/pact_broker/config/save_and_load_spec.rb
|
897
|
+
- spec/lib/pact_broker/config/save_spec.rb
|
884
898
|
- spec/lib/pact_broker/configuration_spec.rb
|
885
899
|
- spec/lib/pact_broker/db/validate_encoding_spec.rb
|
886
900
|
- spec/lib/pact_broker/diagnostic/resources/dependencies_spec.rb
|
@@ -921,6 +935,7 @@ test_files:
|
|
921
935
|
- spec/lib/pact_broker/webhooks/repository_spec.rb
|
922
936
|
- spec/lib/pact_broker/webhooks/service_spec.rb
|
923
937
|
- spec/lib/rack/hal_browser/redirect_spec.rb
|
938
|
+
- spec/lib/rack/pact_broker/add_pact_broker_version_header_spec.rb
|
924
939
|
- spec/migrations/23_pact_versions_spec.rb
|
925
940
|
- spec/migrations/24_populate_pact_contents_spec.rb
|
926
941
|
- spec/migrations/34_latest_tagged_pacts_spec.rb
|