Converted vehicles/ordnance to use sortable's.

master
Pacman Ghost 6 years ago
parent 960266b591
commit b387c2ed80
  1. 6
      vasl_templates/webapp/static/css/tabs-ob.css
  2. 51
      vasl_templates/webapp/static/main.js
  3. 4
      vasl_templates/webapp/static/simple_notes.js
  4. 30
      vasl_templates/webapp/static/snippets.js
  5. 9
      vasl_templates/webapp/static/sortable.js
  6. 149
      vasl_templates/webapp/static/vehicles_ordnance.js
  7. 78
      vasl_templates/webapp/static/vo.js
  8. 12
      vasl_templates/webapp/templates/index.html
  9. 10
      vasl_templates/webapp/templates/vo-report.html
  10. 11
      vasl_templates/webapp/tests/test_scenario_persistence.py
  11. 53
      vasl_templates/webapp/tests/test_vehicles_ordnance.py
  12. 2
      vasl_templates/webapp/tests/utils.py
  13. 3
      vasl_templates/webapp/vehicles_ordnance.py

@ -55,10 +55,10 @@
.panel-vehicles .footer { text-align: right ; font-size: 75% ; }
.panel-vehicles .footer .l { float: left ; }
.vehicle-trash { margin-left: 5px ; height: 2em ; }
.vehicles-trash { margin-left: 5px ; height: 2em ; }
.vehicle-hint { width:100% ; height: calc(100% - 1.5em) ; font-size: 80% ; font-style: italic ; }
.vehicle-hint p { margin-bottom: 1em ; }
.vehicles-hint { width:100% ; height: calc(100% - 1.5em) ; font-size: 80% ; font-style: italic ; }
.vehicles-hint p { margin-bottom: 1em ; }
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

@ -85,9 +85,6 @@ $(document).ready( function () {
function() { add_ssr() ; },
edit_ssr
) ;
$("#panel-ssr input[type='button'][data-id='ssr']").click( function() {
edit_template( "ssr" ) ;
} ) ;
// initialize the scenario notes
init_sortable( $("#scenario_notes-sortable"),
@ -130,31 +127,25 @@ $(document).ready( function () {
edit_template( "ob_note" ) ;
} ) ;
// initialize vehicle controls (1)
$("#vehicle-sortable_1").sortable( { connectWith: "#vehicle-trash_1", cursor: "move" } ) ;
$("#add-vehicle_1").click( function() { add_vo( "vehicle", 1 ) ; } ) ;
$("#vehicle-trash_1").sortable( {
receive: function( evt, ui ) { ui.item.remove() ; update_vo_hint("vehicle",1) ; }
} ) ;
// initialize vehicle controls (2)
$("#vehicle-sortable_2").sortable( { connectWith: "#vehicle-trash_2", cursor: "move" } ) ;
$("#add-vehicle_2").click( function() { add_vo( "vehicle", 2 ) ; } ) ;
$("#vehicle-trash_2").sortable( {
receive: function( evt, ui ) { ui.item.remove() ; update_vo_hint("vehicle",2) ; }
} ) ;
// initialize the OB vehicles
init_sortable( $("#vehicles-sortable_1"),
function() { add_vo( "vehicles", 1 ) ; },
null
) ;
init_sortable( $("#vehicles-sortable_2"),
function() { add_vo( "vehicles", 2 ) ; },
null
) ;
// initialize ordnance controls (1)
$("#ordnance-sortable_1").sortable( { connectWith: "#ordnance-trash_1", cursor: "move" } ) ;
$("#add-ordnance_1").click( function() { add_vo( "ordnance", 1 ) ; } ) ;
$("#ordnance-trash_1").sortable( {
receive: function( evt, ui ) { ui.item.remove() ; update_vo_hint("ordnance",1) ; }
} ) ;
// initialize ordnance controls (2)
$("#ordnance-sortable_2").sortable( { connectWith: "#ordnance-trash_2", cursor: "move" } ) ;
$("#add-ordnance_2").click( function() { add_vo( "ordnance", 2 ) ; } ) ;
$("#ordnance-trash_2").sortable( {
receive: function( evt, ui ) { ui.item.remove() ; update_vo_hint("ordnance",2) ; }
} ) ;
// initialize the OB ordnance
init_sortable( $("#ordnance-sortable_1"),
function() { add_vo( "ordnance", 1 ) ; },
null
) ;
init_sortable( $("#ordnance-sortable_2"),
function() { add_vo( "ordnance", 2 ) ; },
null
) ;
// handle ENTER and double-clicks in the "select vehicle/ordnance" dialog
function auto_select_vo( evt ) {
@ -189,7 +180,7 @@ $(document).ready( function () {
// get the vehicle/ordnance listings
$.getJSON( gVehicleListingsUrl, function(data) {
gVehicleOrdnanceListings.vehicle = data ;
gVehicleOrdnanceListings.vehicles = data ;
} ).fail( function( xhr, status, errorMsg ) {
showErrorMsg( "Can't get the vehicle listings:<div class='pre'>" + escapeHTML(errorMsg) + "</div>" ) ;
} ) ;
@ -396,8 +387,8 @@ function on_player_change( $select )
// reset the OB params
$("textarea[name='OB_SETUP_"+player_id+"']").val( "" ) ;
$("input[name='OB_SETUP_WIDTH_"+player_id+"']").val( "" ) ;
delete_all_vo( "vehicle", player_id ) ;
delete_all_sortable_entries( $( "#vehicles-sortable_" + player_id ) ) ;
$("input[name='VEHICLES_WIDTH_"+player_id+"']").val( "" ) ;
delete_all_vo( "ordnance", player_id ) ;
delete_all_sortable_entries( $( "#ordnance-sortable_" + player_id ) ) ;
$("input[name='ORDNANCE_WIDTH_"+player_id+"']").val( "" ) ;
}

@ -105,7 +105,7 @@ function _make_simple_note( note_type, caption )
{
// generate the sortable entry
var buf = [ "<div>" ] ;
if ( note_type !== "ssr" ) {
if ( ["scenario_notes","ob_setups","ob_notes"].indexOf( note_type ) !== -1 ) {
var note_type0 = note_type.substring( 0, note_type.length-1 ) ;
buf.push( "<input type='button' data-id='" + note_type0 + "' value='Snippet'>" ) ;
}
@ -137,6 +137,6 @@ function _get_note_type_for_sortable( $sortable )
{
// figure out what type of note the sortable has
var id = $sortable.prop( "id" ) ;
var match = /^((scenario_notes|ssr|ob_setups|ob_notes))-sortable(_\d)?$/.exec( id ) ;
var match = /^((scenario_notes|ssr|vehicles|ob_setups|ob_notes))-sortable(_\d)?$/.exec( id ) ;
return match[1] ;
}

@ -210,11 +210,11 @@ function unload_params( params, check_date_capabilities )
params.SSR.push( data[i].caption ) ;
// collect the vehicles/ordnance
function get_vo( vo_type, player_id, paramName )
{
function get_vo( vo_type, player_id, key ) {
var $sortable = $( "#" + vo_type + "-sortable_" + player_id ) ;
var objs = [] ;
$("#"+vo_type+"-sortable_"+player_id+" li").each( function() {
var entry = find_vo( $(this).data("vo-key") ) ;
$sortable.children( "li" ).each( function() {
var entry = $(this).data( "sortable-data" ).vo_entry ;
var obj = {
name: entry.name,
note_number: entry.note_number,
@ -241,10 +241,10 @@ function unload_params( params, check_date_capabilities )
objs.push( obj ) ;
} ) ;
if ( objs.length > 0 )
params[paramName] = objs ;
params[key] = objs ;
}
get_vo( "vehicle", 1, "VEHICLES_1" ) ;
get_vo( "vehicle", 2, "VEHICLES_2" ) ;
get_vo( "vehicles", 1, "VEHICLES_1" ) ;
get_vo( "vehicles", 2, "VEHICLES_2" ) ;
get_vo( "ordnance", 1, "ORDNANCE_1" ) ;
get_vo( "ordnance", 2, "ORDNANCE_2" ) ;
@ -526,12 +526,14 @@ function do_load_scenario( params )
if ( key === "VEHICLES_1" || key === "ORDNANCE_1" || key === "VEHICLES_2" || key === "ORDNANCE_2" ) {
player_id = key.substring( key.length-1 ) ;
var nat = params[ "PLAYER_" + player_id ] ;
var vo_type = key.substring(0,9) === "VEHICLES_" ? "vehicle" : "ordnance" ;
var vo_type = (key.substring(0,9) === "VEHICLES_") ? "vehicles" : "ordnance" ;
for ( i=0 ; i < params[key].length ; ++i ) {
if ( ! do_add_vo( nat, vo_type, player_id, params[key][i] ) )
var entry = find_vo( vo_type, nat, params[key][i] ) ;
if ( entry )
do_add_vo( vo_type, player_id, entry ) ;
else
unknown_vo.push( params[key][i] ) ;
}
update_vo_hint( vo_type, player_id ) ;
params_loaded[key] = true ;
continue ;
}
@ -635,10 +637,10 @@ function on_new_scenario( verbose )
delete_all_sortable_entries( $("#scenario_notes-sortable") ) ;
delete_all_sortable_entries( $("#ssr-sortable") ) ;
for ( var i=1 ; i <= 2 ; ++i ) {
delete_all_sortable_entries( $("#ob_setups-sortable_"+i) ) ;
delete_all_sortable_entries( $("#ob_notes-sortable_"+i) ) ;
delete_all_vo( "vehicle", i ) ;
delete_all_vo( "ordnance", i ) ;
delete_all_sortable_entries( $( "#ob_setups-sortable_" + i ) ) ;
delete_all_sortable_entries( $( "#ob_notes-sortable_" + i ) ) ;
delete_all_sortable_entries( $( "#vehicles-sortable_" + i ) ) ;
delete_all_sortable_entries( $( "#ordnance-sortable_" + i ) ) ;
}
// provide some feedback to the user

@ -42,9 +42,12 @@ function init_sortable_entry( $entry )
{
// initialize the sortable entry
var $sortable = $entry.parent() ;
$entry.dblclick( function() {
$sortable.data("on_edit")( $sortable, $entry ) ;
} ) ;
var on_edit = $sortable.data( "on_edit" ) ;
if ( on_edit ) {
$entry.dblclick( function() {
on_edit( $sortable, $entry ) ;
} ) ;
}
$entry.click( function( evt ) {
if ( evt.ctrlKey )
delete_sortable_entry( $(this) ) ;

@ -1,149 +0,0 @@
function add_vo( vo_type, player_id )
{
// get the vehicles/ordnance already added
var vo_present = [];
$("#"+vo_type+"-sortable_"+player_id+" li").each( function() {
vo_present.push( $(this).text() ) ;
} );
// load the available vehicles/ordnance
var nat = $( "select[name='PLAYER_" + player_id + "']" ).val() ;
var entries = gVehicleOrdnanceListings[vo_type][nat] ;
if ( entries === undefined ) {
showErrorMsg( "There are no " + gTemplatePack.nationalities[nat].display_name + " " + vo_type + " listings." ) ;
return ;
}
var buf = [] ;
for ( var i=0 ; i < entries.length ; ++i ) {
if ( vo_present.indexOf( entries[i].name ) !== -1 )
continue ;
buf.push( "<option value='" + i + "'>" + escapeHTML(entries[i].name) + "</option>" ) ;
}
var $listbox = $( "#select-vo select" ) ;
$listbox.html( buf.join("") ) ;
$listbox.prop( "selectedIndex", 0 ).animate({ scrollTop: 0 }) ;
// let the user select a vehicle/ordnance
$("#select-vo").dialog( {
title: "Add " + vo_type,
dialogClass: "select-vo",
modal: true,
minWidth: 200,
minHeight: 300,
open: function() {
$("#select-vo input[type='text']").val( "" ) ;
$(this).height( $(this).height() ) ; // fudge: force the select to resize
$("#select-vo select").filterByText( $("#select-vo input[type='text']") ) ;
},
buttons: {
OK: function() {
// add the new vehicle/ordnance
var val = $listbox.val() ;
do_add_vo( nat, vo_type, player_id, entries[val].name ) ;
update_vo_hint( vo_type, player_id ) ;
$(this).dialog( "close" ) ;
},
Cancel: function() { $(this).dialog( "close" ) ; },
},
} ) ;
}
function do_add_vo( nat, vo_type, player_id, vo_name )
{
// find the specified vehicle/ordnance
var vo_key = make_vo_key( nat, vo_type, vo_name ) ;
if ( ! find_vo( vo_key ) )
return false ;
// add a new vehicle/ordnance entry
var $sortable = $( "#" + vo_type + "-sortable_" + player_id ) ;
var $elem = $( "<li></li>" ) ;
$elem.text( vo_name ) ;
$elem.data( "vo-key", vo_key ) ;
$sortable.append( $elem ) ;
init_vo( vo_type, player_id, $elem ) ;
return true ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function init_vo( vo_type, player_id, $elem )
{
// initialize vehicle/ordnance element(s)
$elem.click( function( evt ) {
if ( evt.ctrlKey )
delete_vo( vo_type, player_id, $(this) ) ;
} ) ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function update_vo_hint( vo_type, player_id )
{
// show/hide the vehicle/ordnance hint
if ( $("#"+vo_type+"-sortable_"+player_id+" li").length === 0 ) {
$("#"+vo_type+"-sortable_"+player_id).hide() ;
$("#"+vo_type+"-hint_"+player_id).show() ;
} else {
$("#"+vo_type+"-sortable_"+player_id).show() ;
$("#"+vo_type+"-hint_"+player_id).hide() ;
}
}
// --------------------------------------------------------------------
function delete_vo( vo_type, player_id, $elem )
{
// delete the vehicle/ordnance
$elem.addClass( "highlighted" ) ;
ask( "Delete this "+vo_type+"?", escapeHTML($elem.text()), {
"ok": function() {
$elem.remove() ;
update_vo_hint( vo_type, player_id ) ;
},
"close": function() { $elem.removeClass("highlighted") ; },
} ) ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function delete_all_vo( vo_type, player_id )
{
// delete all vehicles/ordnance
$("#"+vo_type+"-sortable_"+player_id+" li").each( function() {
$(this).remove() ;
} ) ;
update_vo_hint( vo_type, player_id ) ;
}
// --------------------------------------------------------------------
var gVehicleOrdnanceIndex = null ;
function find_vo( vo_key )
{
// check if we need to build the index
function build_vo_index( vo_type ) {
for ( var nat in gVehicleOrdnanceListings[vo_type] ) {
for ( var i=0 ; i < gVehicleOrdnanceListings[vo_type][nat].length ; ++i ) {
var entry = gVehicleOrdnanceListings[vo_type][nat][i] ;
gVehicleOrdnanceIndex[ make_vo_key(nat,vo_type,entry.name) ] = entry ;
}
}
}
if ( gVehicleOrdnanceIndex === null ) {
// yup - make it so
gVehicleOrdnanceIndex = {} ;
build_vo_index( "vehicle" ) ;
build_vo_index( "ordnance" ) ;
}
// find a vehicle/ordnance entry
return gVehicleOrdnanceIndex[ vo_key ] ;
}
function make_vo_key( nat, vo_type, name ) {
// generate a key use to identify each vehicle/ordnance
return nat + ":" + vo_type + ":" + name ;
}

@ -0,0 +1,78 @@
// --------------------------------------------------------------------
function add_vo( vo_type, player_id )
{
// get the vehicles/ordnance already added
var $sortable = $( "#" + vo_type + "-sortable_" + player_id ) ;
var vo_present = [];
$sortable.children("li").each( function() {
vo_present.push( $(this).text() ) ;
} );
// load the available vehicles/ordnance
var nat = $( "select[name='PLAYER_" + player_id + "']" ).val() ;
var entries = gVehicleOrdnanceListings[vo_type][nat] ;
if ( entries === undefined ) {
showErrorMsg( "There are no " + gTemplatePack.nationalities[nat].display_name + " " + vo_type + " listings." ) ;
return ;
}
var buf = [] ;
for ( var i=0 ; i < entries.length ; ++i ) {
if ( vo_present.indexOf( entries[i].name ) !== -1 )
continue ;
buf.push( "<option value='" + i + "'>" + escapeHTML(entries[i].name) + "</option>" ) ;
}
var $listbox = $( "#select-vo select" ) ;
$listbox.html( buf.join("") ) ;
$listbox.prop( "selectedIndex", 0 ).animate({ scrollTop: 0 }) ;
// let the user select a vehicle/ordnance
$("#select-vo").dialog( {
title: "Add " + vo_type,
dialogClass: "select-vo",
modal: true,
minWidth: 200,
minHeight: 300,
open: function() {
$("#select-vo input[type='text']").val( "" ) ;
$(this).height( $(this).height() ) ; // fudge: force the select to resize
$("#select-vo select").filterByText( $("#select-vo input[type='text']") ) ;
},
buttons: {
OK: function() {
// add the new vehicle/ordnance
var val = $listbox.val() ;
do_add_vo( vo_type, player_id, entries[val] ) ;
$(this).dialog( "close" ) ;
},
Cancel: function() { $(this).dialog( "close" ) ; },
},
} ) ;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function do_add_vo( vo_type, player_id, entry )
{
// add the specified vehicle/ordnance
var $sortable = $( "#" + vo_type + "-sortable_" + player_id ) ;
add_sortable( $sortable,
$( "<div>" + entry.name + "</div>" ),
{ caption: entry.name, vo_entry: entry }
) ;
}
// --------------------------------------------------------------------
function find_vo( vo_type, nat, name )
{
// find the specificed vehicle/ordnance
var entries = gVehicleOrdnanceListings[vo_type][nat] ;
for ( var i=0 ; i < entries.length ; ++i ) {
if ( entries[i].name === name )
return entries[i] ;
}
return null ;
}

@ -142,13 +142,13 @@
<fieldset class="tr"> <legend>Vehicles</legend>
<div id="panel-vehicles_1" class="panel-vehicles">
<div class="content">
<div id="vehicle-hint_1" class="vehicle-hint"> <p>Click on the "+" below to add a new Vehicle. <p>To re-order the Vehicles, use the mouse to drag them around. <p>Ctrl-click on an Vehicle to delete it, or drag it into the trashcan below. </div>
<ul id="vehicle-sortable_1" class="sortable" style="display:none;"></ul>
<div id="vehicles-hint_1" class="vehicles-hint"> <p>Click on the "+" below to add a new Vehicle. <p>To re-order the Vehicles, use the mouse to drag them around. <p>Ctrl-click on an Vehicle to delete it, or drag it into the trashcan below. </div>
<ul id="vehicles-sortable_1" class="sortable" style="display:none;"></ul>
</div>
<div class="footer">
<div class="l">
<input type="button" id="add-vehicle_1" value="+">
<img id="vehicle-trash_1" class="vehicle-trash" src="{{url_for('static',filename='images/trash.png')}}">
<input type="button" id="vehicles-add_1" value="+">
<img id="vehicles-trash_1" class="vehicles-trash" src="{{url_for('static',filename='images/trash.png')}}">
</div>
<label for="VEHICLES_WIDTH_1">Width:</label>
<input type="text" class="param" name="VEHICLES_WIDTH_1" size="5">
@ -164,7 +164,7 @@
</div>
<div class="footer">
<div class="l">
<input type="button" id="add-ordnance_1" value="+">
<input type="button" id="ordnance-add_1" value="+">
<img id="ordnance-trash_1" class="ordnance-trash" src="{{url_for('static',filename='images/trash.png')}}">
</div>
<label for="ORDNANCE_WIDTH_1">Width:</label>
@ -216,7 +216,7 @@ gOrdnanceListingsUrl = "{{url_for('get_ordnance_listings')}}" ;
<script src="{{url_for('static',filename='main.js')}}"></script>
<script src="{{url_for('static',filename='snippets.js')}}"></script>
<script src="{{url_for('static',filename='simple_notes.js')}}"></script>
<script src="{{url_for('static',filename='vehicles_ordnance.js')}}"></script>
<script src="{{url_for('static',filename='vo.js')}}"></script>
<script src="{{url_for('static',filename='sortable.js')}}"></script>
<script src="{{url_for('static',filename='utils.js')}}"></script>

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<title> {{VO_TYPE}} listings: {{NATIONALITY}} </title>
<title> {{VO_TYPE0}} listings: {{NATIONALITY}} </title>
<style>
table { border-collapse: collapse ; }
th { text-align: left ; padding: 0.2em 0.5em ; background: #eee ; border: 1px solid #ccc ; }
@ -24,14 +24,14 @@ td { padding: 0.2em 0.5em ; }
$(document).ready( function () {
// get the vehicle listings
var url ;
if ( "{{VO_TYPE}}" == "vehicle" )
if ( "{{VO_TYPE}}" == "vehicles" )
url = "{{url_for( 'get_vehicle_listings', report=1 )}}"
else
url = "{{url_for( 'get_ordnance_listings', report=1 )}}" ;
$.getJSON( url, function(data) {
load_vo_listings( data ) ;
} ).fail( function( xhr, status, errorMsg ) {
alert( "Can't get the {{VO_TYPE}} listings:\n\n" + errorMsg ) ;
alert( "Can't get the {{VO_TYPE0}} listings:\n\n" + errorMsg ) ;
} ) ;
} ) ;
@ -52,7 +52,7 @@ function load_vo_listings( objs )
var buf = [] ;
buf.push( "<table>" ) ;
buf.push( "<tr>", "<th>Name" ) ;
if ( "{{VO_TYPE}}" === "vehicle" ) {
if ( "{{VO_TYPE}}" === "vehicles" ) {
buf.push( "<th>Radio" ) ;
buf.push( "<th>Crew survival" ) ;
}
@ -61,7 +61,7 @@ function load_vo_listings( objs )
var obj = objs[nat][i] ;
buf.push( "<tr>" ) ;
buf.push( "<td>", fmtval(obj.name) ) ;
if ( "{{VO_TYPE}}" === "vehicle" ) {
if ( "{{VO_TYPE}}" === "vehicles" ) {
buf.push( "<td>", fmtval(obj.no_radio) ) ;
buf.push( "<td>", fmtval(make_crew_survival(obj)) ) ;
}

@ -75,8 +75,8 @@ def test_scenario_persistence( webapp, webdriver ): #pylint: disable=too-many-lo
ssrs = find_child( "#ssr-sortable" )
ob_setups1, ob_notes1 = find_child("#ob_setups-sortable_1"), find_child("#ob_notes-sortable_1")
ob_setups2, ob_notes2 = find_child("#ob_setups-sortable_2"), find_child("#ob_notes-sortable_2")
vehicles1, ordnance1 = find_child("#vehicle-sortable_1"), find_child("#ordnance-sortable_1")
vehicles2, ordnance2 = find_child("#vehicle-sortable_2"), find_child("#ordnance-sortable_2")
vehicles1, ordnance1 = find_child("#vehicles-sortable_1"), find_child("#ordnance-sortable_1")
vehicles2, ordnance2 = find_child("#vehicles-sortable_2"), find_child("#ordnance-sortable_2")
elems = {
c.get_attribute("name"): c
for elem_type in ("input","textarea","select") for c in find_children(elem_type)
@ -123,6 +123,7 @@ def test_loading_ssrs( webapp, webdriver ):
_ = _save_scenario() # nb: force the "scenario-persistence" element to be created
# initialize
select_tab( "scenario" )
sortable = find_child( "#ssr-sortable" )
def do_test( ssrs ): # pylint: disable=missing-docstring
_load_scenario( { "SSR": ssrs } )
@ -151,15 +152,19 @@ def test_unknown_vo( webapp, webdriver ):
# load a scenario that has unknown vehicles/ordnance
scenario_params = {
"PLAYER_1": "german",
"VEHICLES_1": [ "unknown vehicle 1a", "unknown vehicle 1b" ],
"ORDNANCE_1": [ "unknown ordnance 1a", "unknown ordnance 1b" ],
"PLAYER_2": "russian",
"VEHICLES_2": [ "unknown vehicle 2" ],
"ORDNANCE_2": [ "unknown ordnance 2" ],
}
_load_scenario( scenario_params )
last_warning = get_stored_msg( "_last-warning_" )
assert last_warning.startswith( "Unknown vehicles/ordnance:" )
for vals in scenario_params.values():
for key,vals in scenario_params.items():
if not key.startswith( ("VEHICLES_","ORDNANCE_") ):
continue
assert all( v in last_warning for v in vals )
# ---------------------------------------------------------------------

@ -19,12 +19,12 @@ def test_crud( webapp, webdriver ):
# initialize
_expected = {
("vehicle",1): [], ("ordnance",1): [],
("vehicle",2): [], ("ordnance",2): []
("vehicles",1): [], ("ordnance",1): [],
("vehicles",2): [], ("ordnance",2): []
}
_width = {
("vehicle",1): None, ("ordnance",1): None,
("vehicle",2): None, ("ordnance",2): None
("vehicles",1): None, ("ordnance",1): None,
("vehicles",2): None, ("ordnance",2): None
}
def _add_vo( vo_type, player_id, name ):
@ -54,8 +54,7 @@ def test_crud( webapp, webdriver ):
def _set_width( vo_type, player_id, width ):
"""Set the snippet width."""
select_tab( "ob{}".format( player_id ) )
vo_type2 = "vehicles" if vo_type == "vehicle" else vo_type
elem = find_child( "input[name='{}_WIDTH_{}']".format( vo_type2.upper(), player_id ) )
elem = find_child( "input[name='{}_WIDTH_{}']".format( vo_type.upper(), player_id ) )
elem.clear()
if width is not None:
elem.send_keys( str(width) )
@ -66,8 +65,7 @@ def test_crud( webapp, webdriver ):
# check the snippet
select_tab( "ob{}".format( player_id ) )
dismiss_notifications()
vo_type2 = "vehicles" if vo_type == "vehicle" else vo_type
btn = find_child( "input[type='button'][data-id='{}_{}']".format( vo_type2, player_id ) )
btn = find_child( "input[type='button'][data-id='{}_{}']".format( vo_type, player_id ) )
btn.click()
buf = get_clipboard()
names = [
@ -92,12 +90,13 @@ def test_crud( webapp, webdriver ):
def do_test( vo_type ):
"""Run the test."""
vo_type0 = vo_type[:-1] if vo_type.endswith("s") else vo_type
# add a German vehicle/ordnance
_add_vo( vo_type, 1, "a german {}".format(vo_type) )
_add_vo( vo_type, 1, "a german {}".format(vo_type0) )
# generate a Russian vehicle/ordnance snippet
_check_snippet( vo_type, 2 )
# add a Russian vehicle/ordnance
_add_vo( vo_type, 2, "another russian {}".format(vo_type) )
_add_vo( vo_type, 2, "another russian {}".format(vo_type0) )
# go back and check the German snippet again
_check_snippet( vo_type, 1 )
# add another Russian vehicle/ordnance
@ -105,13 +104,13 @@ def test_crud( webapp, webdriver ):
_add_vo( vo_type, 2, "name only" )
# delete the German vehicle/ordnance
_set_width( vo_type, 1, "100px" )
_delete_vo( vo_type, 1, "a german {}".format(vo_type), webdriver )
_delete_vo( vo_type, 1, "a german {}".format(vo_type0), webdriver )
_set_width( vo_type, 1, None )
_check_snippet( vo_type, 1 )
# go back and check the Russian snippet again
_check_snippet( vo_type, 2 )
# delete the Russian vehicles/ordnance
_delete_vo( vo_type, 2, "another russian {}".format(vo_type), webdriver )
_delete_vo( vo_type, 2, "another russian {}".format(vo_type0), webdriver )
_set_width( vo_type, 2, None )
_delete_vo( vo_type, 2, "name only", webdriver )
# check the final state
@ -119,7 +118,7 @@ def test_crud( webapp, webdriver ):
assert not _expected[ (vo_type,2) ]
# do the test
do_test( "vehicle" )
do_test( "vehicles" )
do_test( "ordnance" )
# ---------------------------------------------------------------------
@ -132,51 +131,51 @@ def test_snippets( webapp, webdriver ):
def do_test( vo_type ):
"""Run the test."""
vo_type2 = "vehicles" if vo_type == "vehicle" else vo_type
vo_type0 = vo_type[:-1] if vo_type.endswith("s") else vo_type
# test a full example
add_vo( vo_type, 1, "a german {}".format(vo_type) )
dismiss_notifications()
btn = find_child( "input[type='button'][data-id='{}_1']".format( vo_type2 ) )
btn = find_child( "input[type='button'][data-id='{}_1']".format( vo_type ) )
btn.click()
expected = [
'[German] ; width=',
'[*] a german {}: #=1'.format( vo_type ),
'[*] a german {}: #=1'.format( vo_type0 ),
'- notes: "A" "B†"',
'- capabilities: "QSU" "IR" "A1" "H2" "can do other stuff"',
'- raw capabilities: "QSU" "IR" "A1" "H2" "can do other stuff"'
]
if vo_type == "vehicle":
if vo_type == "vehicles":
expected.insert( 3, "- CS 5" )
assert get_clipboard() == "\n".join(expected)
delete_vo( vo_type, 1, "a german {}".format(vo_type), webdriver )
delete_vo( vo_type, 1, "a german {}".format(vo_type0), webdriver )
# test a partial example
add_vo( vo_type, 1, "another german {}".format(vo_type) )
dismiss_notifications()
btn = find_child( "input[type='button'][data-id='{}_1']".format( vo_type2 ) )
btn = find_child( "input[type='button'][data-id='{}_1']".format( vo_type ) )
btn.click()
expected = [
'[German] ; width=',
'[*] another german {}: #=2'.format( vo_type ),
'[*] another german {}: #=2'.format( vo_type0 ),
'- capabilities: "QSU"',
'- raw capabilities: "QSU"'
]
if vo_type == "vehicle":
if vo_type == "vehicles":
expected.insert( 2, '- cs 4 <small><i>(brew up)</i></small>' )
assert get_clipboard() == "\n".join(expected)
delete_vo( vo_type, 1, "another german {}".format(vo_type), webdriver )
delete_vo( vo_type, 1, "another german {}".format(vo_type0), webdriver )
# test a minimal example
add_vo( vo_type, 1, "name only" )
dismiss_notifications()
btn = find_child( "input[type='button'][data-id='{}_1']".format( vo_type2 ) )
btn = find_child( "input[type='button'][data-id='{}_1']".format( vo_type ) )
btn.click()
assert get_clipboard() == \
'''[German] ; width=
[*] name only: #='''
# do the test
do_test( "vehicle" )
do_test( "vehicles" )
do_test( "ordnance" )
# ---------------------------------------------------------------------
@ -188,7 +187,7 @@ def test_variable_capabilities( webapp, webdriver ):
webdriver.get( webapp.url_for( "main" ) )
# add a vehicle
add_vo( "vehicle", 2, "Churchill III(b)" )
add_vo( "vehicles", 2, "Churchill III(b)" )
# change the scenario date and check the generated snippet
vehicles2 = find_child( "input.generate[data-id='vehicles_2']" )
@ -221,10 +220,10 @@ def add_vo( vo_type, player_id, name ):
# add the vehicle/ordnance
select_tab( "ob{}".format( player_id ) )
elem = find_child( "#add-{}_{}".format( vo_type, player_id ) )
elem = find_child( "#{}-add_{}".format( vo_type, player_id ) )
elem.click()
sel = Select( find_child( "#select-vo select" ) )
sel.select_by_visible_text( name )
sel.select_by_visible_text( name[:-1] if name.endswith("s") else name )
click_dialog_button( "OK" )
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@ -128,8 +128,8 @@ def set_template_params( params ): #pylint: disable=too-many-branches
# check for vehicles/ordnance (these require special handling)
if key in ("VEHICLES_1","ORDNANCE_1","VEHICLES_2","ORDNANCE_2"):
# add them in (nb: we don't consider any existing vehicles/ordnance)
vo_type = "vehicle" if key.startswith("VEHICLES_") else "ordnance"
from vasl_templates.webapp.tests.test_vehicles_ordnance import add_vo #pylint: disable=cyclic-import
vo_type = key[:key.index("_")].lower()
for vo_name in val:
add_vo( vo_type, int(key[-1]), vo_name )
continue

@ -55,6 +55,7 @@ def get_vo_report( nat, vo_type, year ):
abort( 404 )
return render_template( "vo-report.html",
NATIONALITY = nat,
VO_TYPE = "vehicle" if vo_type == "vehicles" else vo_type,
VO_TYPE = vo_type,
VO_TYPE0 = vo_type[:-1] if vo_type.endswith("s") else vo_type,
YEAR = year
)

Loading…
Cancel
Save