Skip to content

Commit cbf0837

Browse files
committed
feat(matrix ui): add form
1 parent 15c7d93 commit cbf0837

File tree

11 files changed

+173
-57
lines changed

11 files changed

+173
-57
lines changed

lib/pact_broker/error.rb

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module PactBroker
2+
3+
class Error < StandardError; end
4+
5+
end

lib/pact_broker/matrix/parse_query.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ def self.call query
77
params = Rack::Utils.parse_nested_query(query)
88
selectors = (params['q'] || []).collect do |i|
99
p = {}
10-
p[:pacticipant_name] = i['pacticipant'] if i['pacticipant']
11-
p[:pacticipant_version_number] = i['version'] if i['version']
10+
p[:pacticipant_name] = i['pacticipant'] if i['pacticipant'] && i['pacticipant'] != ''
11+
p[:pacticipant_version_number] = i['version'] if i['version'] && i['version'] != ''
1212
p[:latest] = true if i['latest'] == 'true'
13-
p[:tag] = i['tag'] if i['tag']
13+
p[:tag] = i['tag'] if i['tag'] && i['tag'] != ''
1414
p
1515
end
1616
options = {}

lib/pact_broker/matrix/repository.rb

+5-32
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
require 'pact_broker/repositories/helpers'
22
require 'pact_broker/matrix/row'
33
require 'pact_broker/matrix/latest_row'
4+
require 'pact_broker/error'
45

56
module PactBroker
67
module Matrix
8+
9+
class Error < PactBroker::Error; end
10+
711
class Repository
812
include PactBroker::Repositories::Helpers
913
include PactBroker::Repositories
@@ -78,7 +82,7 @@ def look_up_versions_for_latest_and_tag(selectors, options)
7882
# resource validation currently stops tag being specified without latest=true
7983
if selector[:tag] && selector[:latest]
8084
version = version_repository.find_by_pacticpant_name_and_latest_tag(selector[:pacticipant_name], selector[:tag])
81-
raise "Could not find version with tag #{selector[:tag].inspect} for #{selector[:pacticipant_name]}" unless version
85+
raise Error.new("Could not find version with tag #{selector[:tag].inspect} for #{selector[:pacticipant_name]}") unless version
8286
# validation in resource should ensure we always have a version
8387
{
8488
pacticipant_name: selector[:pacticipant_name],
@@ -122,37 +126,6 @@ def all_pacticipant_names_in_specified_matrix(selectors, options)
122126
.flatten
123127
.uniq
124128
end
125-
126-
# def where_row_matches_selectors selectors, query
127-
# if selectors.size == 1
128-
# where_consumer_or_provider_is(selectors.first, query)
129-
# else
130-
# where_consumer_and_provider_in(selectors, query)
131-
# end
132-
# end
133-
134-
# def where_consumer_and_provider_in selectors, query
135-
# query.where{
136-
# Sequel.&(
137-
# Sequel.|(
138-
# *selectors.collect{ |s| s[:pacticipant_version_number] ? Sequel.&(consumer_name: s[:pacticipant_name], consumer_version_number: s[:pacticipant_version_number]) : Sequel.&(consumer_name: s[:pacticipant_name]) }
139-
# ),
140-
# Sequel.|(
141-
# *(selectors.collect{ |s| s[:pacticipant_version_number] ? Sequel.&(provider_name: s[:pacticipant_name], provider_version_number: s[:pacticipant_version_number]) : Sequel.&(provider_name: s[:pacticipant_name]) } +
142-
# selectors.collect{ |s| Sequel.&(provider_name: s[:pacticipant_name], provider_version_number: nil) })
143-
# )
144-
# )
145-
# }
146-
# end
147-
148-
# def where_consumer_or_provider_is s, query
149-
# query.where{
150-
# Sequel.|(
151-
# s[:pacticipant_version_number] ? Sequel.&(consumer_name: s[:pacticipant_name], consumer_version_number: s[:pacticipant_version_number]) : Sequel.&(consumer_name: s[:pacticipant_name]),
152-
# s[:pacticipant_version_number] ? Sequel.&(provider_name: s[:pacticipant_name], provider_version_number: s[:pacticipant_version_number]) : Sequel.&(provider_name: s[:pacticipant_name])
153-
# )
154-
# }
155-
# end
156129
end
157130
end
158131
end

lib/pact_broker/matrix/service.rb

+1-3
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ def validate_selectors selectors
2424
error_messages = []
2525

2626
selectors.each do | s |
27-
if s[:pacticipant_name].nil? && s[:pacticipant_version_number].nil?
28-
error_messages << "Please specify the pacticipant name and version"
29-
elsif s[:pacticipant_name].nil?
27+
if s[:pacticipant_name].nil?
3028
error_messages << "Please specify the pacticipant name"
3129
else
3230
if s.key?(:pacticipant_version_number) && s.key?(:latest)

lib/pact_broker/ui/app.rb

+15
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,22 @@
33
require 'pact_broker/ui/controllers/matrix'
44
require 'pact_broker/doc/controllers/app'
55

6+
67
module PactBroker
78
module UI
9+
class PathInfoFixer
10+
PATH_INFO = 'PATH_INFO'.freeze
11+
12+
def initialize app
13+
@app = app
14+
end
15+
16+
def call env
17+
env[PATH_INFO] = '/' if env[PATH_INFO] == ''
18+
@app.call(env)
19+
end
20+
end
21+
822
class App
923

1024
def initialize
@@ -23,6 +37,7 @@ def initialize
2337
end
2438

2539
map "/matrix" do
40+
use PathInfoFixer
2641
run PactBroker::UI::Controllers::Matrix
2742
end
2843

lib/pact_broker/ui/controllers/matrix.rb

+41-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
require 'pact_broker/ui/controllers/base_controller'
22
require 'pact_broker/ui/view_models/matrix_line'
3+
require 'pact_broker/matrix/parse_query'
4+
require 'pact_broker/logging'
35
require 'haml'
46

57
module PactBroker
@@ -8,11 +10,38 @@ module Controllers
810
class Matrix < Base
911

1012
include PactBroker::Services
13+
include PactBroker::Logging
14+
15+
get "/" do
16+
selectors = [OpenStruct.new, OpenStruct.new]
17+
locals = {
18+
lines: [],
19+
title: "The Matrix",
20+
selectors: create_selector_objects(selectors)
21+
}
22+
begin
23+
if params[:q]
24+
selectors, options = PactBroker::Matrix::ParseQuery.call(request.env['QUERY_STRING'])
25+
locals[:selectors] = create_selector_objects(selectors)
26+
errors = matrix_service.validate_selectors(selectors)
27+
if errors.empty?
28+
lines = matrix_service.find(selectors, options)
29+
locals[:lines] = lines.collect{ |line| PactBroker::UI::ViewDomain::MatrixLine.new(line) }
30+
else
31+
locals[:errors] = errors
32+
end
33+
end
34+
rescue StandardError => e
35+
log_error e
36+
locals[:errors] = [e.message]
37+
end
38+
haml :'matrix/show', {locals: locals, layout: :'layouts/main'}
39+
end
1140

1241
get "/provider/:provider_name/consumer/:consumer_name" do
1342
selectors = [{ pacticipant_name: params[:consumer_name] }, { pacticipant_name: params[:provider_name] } ]
1443
lines = matrix_service.find(selectors, {latestby: 'cvpv', limit: 1000})
15-
lines = lines.collect{|line| PactBroker::UI::ViewDomain::MatrixLine.new(line) }.sort
44+
lines = lines.collect{ |line| PactBroker::UI::ViewDomain::MatrixLine.new(line) }.sort
1645
locals = {
1746
lines: lines,
1847
title: "The Matrix",
@@ -22,6 +51,17 @@ class Matrix < Base
2251
haml :'matrix/show', {locals: locals, layout: :'layouts/main'}
2352
end
2453

54+
def create_selector_objects(selector_hashes)
55+
selector_hashes.collect do | selector_hash |
56+
o = OpenStruct.new(selector_hash)
57+
o.tag_disabled = o.tag ? nil : 'disabled'
58+
o.version_disabled = o.pacticipant_version_number ? nil : 'disabled'
59+
o.specify_latest_tag_checked = o.tag ? 'checked' : nil
60+
o.specify_version_checked = o.pacticipant_version_number ? 'checked' : nil
61+
o.specify_all_versions_checked = !(o.tag || o.pacticipant_version_number) ? 'checked' : nil
62+
o
63+
end
64+
end
2565
end
2666
end
2767
end

lib/pact_broker/ui/views/matrix/show.haml

+38-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,51 @@
11
%body
22
%link{rel: 'stylesheet', href: '/css/bootstrap.min.css'}
33
%link{rel: 'stylesheet', href: '/stylesheets/index.css'}
4+
%link{rel: 'stylesheet', href: '/stylesheets/matrix.css'}
45
%script{type: 'text/javascript', src:'/javascripts/jquery-2.1.1.min.js'}
56
%script{type: 'text/javascript', src:'/javascripts/jquery.tablesorter.min.js'}
7+
%script{type: 'text/javascript', src:'/javascripts/matrix.js'}
68
%script{type: 'text/javascript', src:'/js/bootstrap.min.js'}
79

810
.container
911
%h1.page-header
1012
= title
13+
14+
- if defined?(errors) && errors.any?
15+
- errors.each do | error |
16+
%div.alert.alert-danger
17+
= error
18+
19+
%form{action: '/matrix', onsubmit:'return onSubmit()'}
20+
- selectors.each_with_index do | selector, index |
21+
.selector
22+
%label{for: "pacticipant#{index}"}
23+
Pacticipant name
24+
%input{name: 'q[]pacticipant', id: "pacticipant1#{index}", value: selector.pacticipant_name}
25+
26+
.input-group
27+
%input{type: 'radio', name: "ignorethis#{index}", class: 'specify-all-versions version-selectorizor', value: 'all_versions', id: "pacticipant#{index}_all_versions", checked: selector.specify_all_versions_checked}
28+
%label{for: "pacticipant#{index}_all_versions"}
29+
All versions
30+
31+
.input-group
32+
%input{type: 'radio', name: "ignorethis#{index}", class: 'specify-version version-selectorizor', value: 'version', id: "pacticipant#{index}_by_version", checked: selector.specify_version_checked}
33+
%label{for: "pacticipant#{index}_by_version"}
34+
Version
35+
%input{name: 'q[]version', type: 'text', id: "pacticipant#{index}_version", class: 'by-version', value: selector.pacticipant_version_number}
36+
37+
.input-group
38+
%input{type: 'radio', name: "ignorethis#{index}", class: 'specify-latest-tag version-selectorizor', value: 'tag', id: "pacticipant#{index}_by_tag", checked: selector.specify_latest_tag_checked}
39+
%label{for: "pacticipant#{index}_by_tag"}
40+
Latest version with tag
41+
%input{name: 'q[]tag', type: 'text', id: "pacticipant#{index}_tag", class: "by-latest-tag", value: selector.tag}
42+
%input{name: 'q[]latest', value: 'true', hidden: true, class: 'latest-flag'}
43+
44+
%div
45+
%input{type: 'submit'}
46+
47+
48+
1149
%table.table.table-bordered.table-striped{id: 'matrix'}
1250
%thead
1351
%th.consumer
@@ -45,13 +83,3 @@
4583
= line.provider_version_number
4684
%td.verification-result{class: line.verification_status_class}
4785
= line.verification_status
48-
49-
:javascript
50-
$(function(){
51-
$("#matrix").tablesorter({
52-
textExtraction : function(node, table, cellIndex){
53-
n = $(node);
54-
return n.attr('data-sort-value') || n.text();
55-
}
56-
});
57-
});

public/javascripts/matrix.js

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
function handleRadioButtonClicked() {
2+
selectApplicableTextBox($(this));
3+
}
4+
5+
function selectApplicableTextBox(selectedRadioButton) {
6+
selectedRadioButton.closest('.input-group').find('input[type="text"]').first().focus();
7+
}
8+
9+
function handleTextBoxClicked() {
10+
selectApplicableRadioButton($(this));
11+
clearOtherTextBoxes($(this));
12+
}
13+
14+
function selectApplicableRadioButton(selectedTextBox) {
15+
selectedTextBox.closest('.input-group').find('.version-selectorizor').prop('checked', 'checked');
16+
}
17+
18+
function clearOtherTextBoxes(selectedTextBox) {
19+
selectedTextBox.closest('.selector').find('input[type="text"]').each(function(){
20+
if(!selectedTextBox.is($(this))) {
21+
$(this).prop('value', '');
22+
}
23+
});
24+
}
25+
26+
function onSubmit() {
27+
disableFieldsThatShouldNotBeSubmitted();
28+
return true;
29+
}
30+
31+
function disableFieldsThatShouldNotBeSubmitted() {
32+
disableInputsForUncheckedRadioButtons();
33+
disableRadioButtons();
34+
}
35+
36+
function disableInputsForUncheckedRadioButtons() {
37+
$('.version-selectorizor').each(function(){
38+
if($(this).prop('checked') === false) {
39+
$(this).closest('.input-group').find('input').prop('disabled', 'disabled');
40+
}
41+
});
42+
}
43+
44+
function disableRadioButtons() {
45+
$('.version-selectorizor').prop('disabled', 'disabled');
46+
}
47+
48+
$(document).ready(function(){
49+
$('.by-version').click(handleTextBoxClicked);
50+
$('.by-latest-tag').click(handleTextBoxClicked);
51+
$('.version-selectorizor').click(handleRadioButtonClicked);
52+
53+
$("#matrix").tablesorter({
54+
textExtraction : function(node, table, cellIndex){
55+
n = $(node);
56+
return n.attr('data-sort-value') || n.text();
57+
}
58+
});
59+
});

public/stylesheets/matrix.css

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.input-group {
2+
display: inline-block;
3+
padding-left: 20px
4+
}

script/seed-matrix.rb

+2
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@
4141

4242
TestDataBuilder.new
4343
.create_pact_with_hierarchy("A", "1", "B")
44+
.create_consumer_version_tag("master")
4445
.create_verification(provider_version: '1', success: false)
4546
.create_verification(provider_version: '1', number: 2, success: true)
4647
.create_verification(provider_version: '2', number: 3)
4748
.create_verification(provider_version: '4', number: 4)
4849
.create_provider_version("5")
4950
.use_consumer("B")
5051
.use_consumer_version("1")
52+
.create_consumer_version_tag("master")
5153
.create_provider("C")
5254
.create_pact
5355
.create_verification(provider_version: '1', success: false)

spec/lib/pact_broker/matrix/service_spec.rb

-8
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,6 @@ module Matrix
6363
end
6464
end
6565

66-
context "when the pacticipant name and version are not specified" do
67-
let(:selectors) { [{ pacticipant_name: nil, pacticipant_version_number: nil }] }
68-
69-
it "returns error messages" do
70-
expect(subject.first).to eq "Please specify the pacticipant name and version"
71-
end
72-
end
73-
7466
context "when the latest_tag is used instead of a version" do
7567
before do
7668
td.create_pacticipant("Foo")

0 commit comments

Comments
 (0)