From 67c9a40580a772ef0e76afe68bb7e0111ed5dbcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Demians?= Date: Mon, 16 Dec 2013 07:44:52 +0100 Subject: [PATCH] Bug 11396 Test translated SQL installer files Identify missing/supernumeray SQL INSERT in translated SQL files. It would help to avoid inconsitency between master 'en' SQL files and translated version. Several SQL files are tested: - user flags - user permission - biblio framework - authorities framework biblio/authorities framework are in the code, but not yet enabled. To test on master: (1) prove -v xt/db_translate.t (2) You can see that fr-FR/1-Obligatoire/userflags.sql is missing one user flag: 17-staff access. (3) Edit fr-FR/1-Obligatoire/userflags.sql. Add this line: INSERT INTO `userflags` VALUES(17,'staffaccess','Autorisation de modifier les permissions des autres utilisateurs',0); (4) prove -v xt/db_translate.t No more test failing. (5) Edit de-DE/mandatory/userpermissions.sql. Suppress line 2. (6) Run the test: you get a new test fail --- xt/db_translate.t | 279 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 279 insertions(+), 0 deletions(-) create mode 100755 xt/db_translate.t diff --git a/xt/db_translate.t b/xt/db_translate.t new file mode 100755 index 0000000..1304c55 --- /dev/null +++ b/xt/db_translate.t @@ -0,0 +1,279 @@ +#!/usr/bin/perl + +# Copyright (C) 2013 Tamil s.a.r.l. +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; +use Test::More qw/no_plan/; +use File::Find; +use IO::String; +use Text::CSV; + + +my $test; +$test = { + + base => "installer/data/mysql/", + + # FIXME: This array can be completed to reference other SQL files to be + # tested, for various languages. 'Tester' analyzes SQL files, parse them, + # and so must be adapted to each type of SQL file. For the time being two + # tests are available: (1) for biblio framework: procedure + # 'framework_biblios' and (2) for authorities frameworks: procedure + # 'framework_authorities'. + files => [ + #{ + # source => 'en/marcflavour/marc21/mandatory/marc21_framework_DEFAULT.sql', + # target => 'es-ES/marcflavour/marc21/mandatory/marc21_framework_DEFAULT.sql', + # description => 'es-ES MARC21 biblio framework', + # proc => 'framework_biblios', + #}, + #{ + # source => 'en/marcflavour/marc21/mandatory/authorities_normal_marc21.sql', + # target => 'es-ES/marcflavour/marc21/mandatory/authorities_normal_marc21.sql', + # description => 'es-ES MARC21 authoritity framework', + # proc => 'framework_authorities', + #}, + #{ + # source => 'fr-FR/marcflavour/unimarc_complet/Obligatoire/framework_DEFAULT.sql', + # target => 'en/marcflavour/unimarc/mandatory/unimarc_framework_DEFAULT.sql', + # description => 'en UNIMARC biblio framework', + # proc => 'framework_biblios', + #}, + { + source => 'en/mandatory/userflags.sql', + target => 'fr-FR/1-Obligatoire/userflags.sql', + description => 'fr-FR user flags', + proc => 'p_userflags', + }, + { + source => 'en/mandatory/userpermissions.sql', + target => 'fr-FR/1-Obligatoire/userpermissions.sql', + description => 'fr-FR user flags', + proc => 'p_userflags', + }, + { + source => 'en/mandatory/userflags.sql', + target => 'de-DE/mandatory/userflags.sql', + description => 'de-DE user flags', + proc => 'p_userflags', + }, + { + source => 'en/mandatory/userpermissions.sql', + target => 'de-DE/mandatory/userpermissions.sql', + description => 'de-DE user permissions', + proc => 'p_userflags', + }, + { + source => 'en/mandatory/userflags.sql', + target => 'it-IT/necessari/userflags.sql', + description => 'it-IT user flags', + proc => 'p_userflags', + }, + { + source => 'en/mandatory/userflags.sql', + target => 'es-ES/mandatory/userflags.sql', + description => 'es-ES user flags', + proc => 'p_userflags', + }, + { + source => 'en/mandatory/userflags.sql', + target => 'pl-PL/mandatory/userflags.sql', + description => 'pl-PL user flags', + proc => 'p_userflags', + }, + { + source => 'en/mandatory/userflags.sql', + target => 'uk-UA/mandatory/permissions_and_user_flags.sql', + description => 'uk-UA user flags', + proc => 'p_userflags', + }, + { + source => 'en/mandatory/userflags.sql', + target => 'ru-RU/mandatory/permissions_and_user_flags.sql', + description => 'ru-RU user flags', + proc => 'p_userflags', + }, + { + source => 'en/mandatory/userflags.sql', + target => 'nb-NO/1-Obligatorisk/userflags.sql', + description => 'nb-NO user flags', + proc => 'p_userflags', + }, + ], + + current => undef, + + csv => Text::CSV->new( + { binary => 1, quote_char => "'", escape_char => '\\', allow_whitespace => 1, } ), + + key => {}, + + fh => { source => undef, target => undef }, + + # Read source/targer files. Populate keys identifying inserted values in + # SQL tables. + # Parameter: a function which build keys, by category of key... + populate => sub { + my $addkey = shift; + + for my $where ( qw/source target/ ) { + my $fh = $test->{fh}->{$where}; + while (<$fh>) { + chop; + next if /^ *--/; + next unless /\((.*)\)/; + $addkey->($where, $1); + } + } + }, + + missing => sub { + my ($what, $label) = @_; + my $s = $test->{key}->{source}->{$what}; + my $t = $test->{key}->{target}->{$what}; + my $count_source = scalar keys %$s; + my $count_target = scalar keys %$t; + return if $count_source == 0; + ok( $count_source == $count_target, + "Count master $label [$count_source] = count translated [$count_target]" ); + my @missing = sort grep { ! $t->{$_} } keys %$s; + fail( "Missing $label in translated file: " . join(', ', @missing) ) if @missing; + my @supernumerary = sort grep { ! $s->{$_} } keys %$t; + fail( "Supernumerary $label found in translated file: " . join(', ', @supernumerary) ) + if @supernumerary; + }, + + def_open => sub { + for my $where ( qw/source target/ ) { + my $c = $test->{current}; + open my $fh, '<', $test->{base} . $c->{$where}; + ok( $fh, "$test->{current}->{description} - $where file '$c->{$where}' exists"); + $test->{fh}->{$where} = $fh; + } + }, + + framework_biblios => sub { + $test->{def_open}->(); + my $k = $test->{key} = {}; + my $addkey = sub { + my ($where, $what) = @_; + $what =~ s/\\"//g; + my $io = IO::String->new(\$what); + my $e = $test->{csv}->getline($io); + return unless $e; + given (scalar @$e) { + when (7) { + $k->{$where}->{field}->{$e->[6] . $e->[0]} = 1; + } + when (17) { + $k->{$where}->{subfield}->{$e->[0] . '$' . $e->[1]} = 1; + } + } + }; + $test->{populate}->($addkey); + $test->{missing}->('field', 'fields'); + $test->{missing}->('subfield', 'subfields'); + }, + + framework_authorities => sub { + my $tr = shift; + $test->{def_open}->($tr); + my $k = $test->{key} = {}; + my $addkey = sub { + my ($where, $what) = @_; + $what =~ s/\\"//g; + my $io = IO::String->new(\$what); + my $e = $test->{csv}->getline($io); + return unless $e; + given (scalar @$e) { + when (16) { + $k->{$where}->{subfield}->{ + $e->[0] . $e->[1] . $e->[2]} = 1; + } + when (4) { + $k->{$where}->{type}->{$e->[0]} = 1; + } + when (7) { + $k->{$where}->{field}->{$e->[0] . $e->[1]} = 1; + } + } + }; + $test->{populate}->($addkey); + $test->{missing}->('type', 'auth types'); + $test->{missing}->('field', 'fields'); + $test->{missing}->('subfield', 'subfields'); + }, + + p_userflags => sub { + my $tr = shift; + $test->{def_open}->($tr); + my $k = $test->{key} = {}; + my $addkey = sub { + my ($where, $what) = @_; + $what =~ s/\\"//g; + $what =~ s/''/\\'/g; + return if $what =~ /bit.*flag/; + my $io = IO::String->new(\$what); + my $e = $test->{csv}->getline($io); + return unless $e; + given (scalar @$e) { + when (4) { + $k->{$where}->{tag}->{$e->[0] . '-' . $e->[1]} = 1; + } + when (3) { + return if $e->[0] eq 'module_bit'; + $k->{$where}->{perm}->{$e->[0] . '-' . $e->[1]} = 1; + } + } + }; + $test->{populate}->($addkey); + $test->{missing}->('tag', 'user tags'); + $test->{missing}->('perm', 'user permissions'); + }, + + run => sub { + for my $current (@{$test->{files}}) { + my $proc_name = $current->{proc}; + my $proc = $test->{$proc_name}; + die "Unknown test procedure: $proc_name" unless $proc; + $test->{current} = $current; + $proc->(); + } + }, + +}; + + +$test->{run}->(); + + +=head1 NAME + +db_translate.t + +=head1 DESCRIPTION + +This test validate DB translation by comparing the master 'en' version whith +the translated version. + +For example, + +prove -v xt/db_translate.t + +=cut + -- 1.7.2.5