#!/bin/bash
# Test case for Evince bug:
#   Bug 639003 - Save Settings as default doesn't work
#   https://bugzilla.gnome.org/show_bug.cgi?id=639003
# Usage: test-639003.sh file.pdf

# Test Evince before and after the fix.
#   Before: /usr/bin/evince
#   After:  /usr/bin/jhbuild run evince
#   Local:  /usr/local/bin/evince
# evince="/usr/bin/evince"
# evince="/usr/bin/jhbuild run evince"
evince="/usr/local/bin/evince"

schema="org.gnome.Evince.Default"
error_log="error.log"

pass="Test passed."
fail="=== TEST FAILED ==="

test_attr="page"
test_value="0"

gsettings="/usr/bin/gsettings"
gvfs_set="/usr/bin/gvfs-set-attribute --type string"
gvfs_unset="/usr/bin/gvfs-set-attribute --type unset"
sync="/bin/sync"
sleep="/bin/sleep 1"

# Launches Evince with error messages redirected to a file.
# Parameters: file.pdf
function launch_evince () {
    # Added sleep to avoid intermittent segmentation fault in the
    # Evince 3.2.1 of Ubuntu 11.10.
    $sleep
    $evince "$1" 2> $error_log
}

# Pauses until told to continue.
function pause () {
    read -p "Press a key to continue..."
}

# Lists all saved settings.
function list_saved_settings () {
    $gsettings list-recursively $schema
}

# Resets all saved settings to their default values.
function reset_saved_settings () {
    $gsettings reset-recursively $schema
    $sync
}

# Sets the saved setting to the specified value.
# Parameters: key value
function set_saved_setting () {
    $gsettings set $schema "$1" "$2"
    $sync
}

# Sets the Evince metadata attribute to the specified value.
# Parameters: file.pdf attribute value
function set_attribute () {
    $gvfs_set "$1" "metadata::evince::${2}" "$3"
    $sync
}

# Unsets all Evince metadata attributes for the specified file.
# Parameters: file.pdf
function clear_all_attributes () {
    $gvfs_unset "$1" "metadata::evince::collate"
    $gvfs_unset "$1" "metadata::evince::continuous"
    $gvfs_unset "$1" "metadata::evince::dual-page"
    $gvfs_unset "$1" "metadata::evince::fullscreen"
    $gvfs_unset "$1" "metadata::evince::inverted-colors"
    $gvfs_unset "$1" "metadata::evince::n-copies"
    $gvfs_unset "$1" "metadata::evince::number-up"
    $gvfs_unset "$1" "metadata::evince::page"
    $gvfs_unset "$1" "metadata::evince::page-set"
    $gvfs_unset "$1" "metadata::evince::page-setup-margin-bottom"
    $gvfs_unset "$1" "metadata::evince::page-setup-margin-left"
    $gvfs_unset "$1" "metadata::evince::page-setup-margin-right"
    $gvfs_unset "$1" "metadata::evince::page-setup-margin-top"
    $gvfs_unset "$1" "metadata::evince::page-setup-orientation"
    $gvfs_unset "$1" "metadata::evince::presentation"
    $gvfs_unset "$1" "metadata::evince::print-pages"
    $gvfs_unset "$1" "metadata::evince::reverse"
    $gvfs_unset "$1" "metadata::evince::rotation"
    $gvfs_unset "$1" "metadata::evince::scale"
    $gvfs_unset "$1" "metadata::evince::show_toolbar"
    $gvfs_unset "$1" "metadata::evince::sidebar_page"
    $gvfs_unset "$1" "metadata::evince::sidebar_size"
    $gvfs_unset "$1" "metadata::evince::sidebar_visibility"
    $gvfs_unset "$1" "metadata::evince::sizing_mode"
    $gvfs_unset "$1" "metadata::evince::window_height"
    $gvfs_unset "$1" "metadata::evince::window_maximized"
    $gvfs_unset "$1" "metadata::evince::window_width"
    $gvfs_unset "$1" "metadata::evince::window_x"
    $gvfs_unset "$1" "metadata::evince::window_y"
    $gvfs_unset "$1" "metadata::evince::zoom"
    $sync
}

# Setting:      continuous = true
# Attribute:    continuous = 1
function test_continuous () {
    echo "Testing View > Continuous."
    reset_saved_settings
    set_saved_setting continuous false

    echo "Continuous should be un-checked (show page at a time) ..."
    clear_all_attributes "$1"
    launch_evince "$1"

    echo "Continuous should be checked (show entire document) ..."
    clear_all_attributes "$1"
    set_attribute "$1" continuous 1
    launch_evince "$1"

    echo "Is Continuous checked or un-checked ...?"
    clear_all_attributes "$1"
    set_attribute "$1" $test_attr $test_value
    launch_evince "$1"

    select answer in checked un-checked; do
        case $answer in
            un-checked) echo "$pass"; break;;
            checked) echo "$fail"; break;;
        esac
    done
}

# Setting:      dual-page = false
# Attribute:    dual-page = 0
function test_dual_page () {
    echo "Testing View > Dual."
    reset_saved_settings
    set_saved_setting dual-page true

    echo "Dual should be checked (show two pages at once) ..."
    clear_all_attributes "$1"
    launch_evince "$1"

    echo "Dual should be un-checked (show one page at a time) ..."
    clear_all_attributes "$1"
    set_attribute "$1" dual-page 0
    launch_evince "$1"

    echo "Is Dual checked or un-checked ...?"
    clear_all_attributes "$1"
    set_attribute "$1" $test_attr $test_value
    launch_evince "$1"

    select answer in checked un-checked; do
        case $answer in
            checked) echo "$pass"; break;;
            un-checked) echo "$fail"; break;;
        esac
    done
}

# Setting:      fullscreen = false
# Attribute:    fullscreen = 0
function test_fullscreen () {
    echo "Testing View > Fullscreen."
    reset_saved_settings
    set_saved_setting fullscreen true

    echo "The document should be fullscreen (window fills screen) ..."
    clear_all_attributes "$1"
    launch_evince "$1"

    echo "The document should not be fullscreen (normal window) ..."
    clear_all_attributes "$1"
    set_attribute "$1" fullscreen 0
    launch_evince "$1"

    echo "Is the document fullscreen or not ...?"
    clear_all_attributes "$1"
    set_attribute "$1" $test_attr $test_value
    launch_evince "$1"

    select answer in fullscreen not; do
        case $answer in
            fullscreen) echo "$pass"; break;;
            not) echo "$fail"; break;;
        esac
    done
}

# Setting:      inverted-colors = false
# Attribute:    inverted-colors = 0
function test_inverted_colors () {
    echo "Testing View > Inverted Colors."
    reset_saved_settings
    set_saved_setting inverted-colors true

    echo "Inverted Colors should be checked (colors inverted) ..."
    clear_all_attributes "$1"
    launch_evince "$1"

    echo "Inverted Colors should be un-checked (normal colors) ..."
    clear_all_attributes "$1"
    set_attribute "$1" inverted-colors 0
    launch_evince "$1"

    echo "Are the colors inverted or not ...?"
    clear_all_attributes "$1"
    set_attribute "$1" $test_attr $test_value
    launch_evince "$1"

    select answer in inverted not; do
        case $answer in
            inverted) echo "$pass"; break;;
            not) echo "$fail"; break;;
        esac
    done
}

# Setting:      show-sidebar = true
# Attribute:    sidebar_visibility = 1
function test_show_sidebar () {
    echo "Testing View > Side Pane."
    reset_saved_settings
    set_saved_setting show-sidebar false

    echo "Side Pane should be un-checked (no side pane) ..."
    clear_all_attributes "$1"
    launch_evince "$1"

    echo "Side Pane should be checked (side pane visible) ..."
    clear_all_attributes "$1"
    set_attribute "$1" sidebar_visibility 1
    launch_evince "$1"

    echo "Is the Side Pane visible or not ...?"
    clear_all_attributes "$1"
    set_attribute "$1" $test_attr $test_value
    launch_evince "$1"

    select answer in visible not; do
        case $answer in
            not) echo "$pass"; break;;
            visible) echo "$fail"; break;;
        esac
    done
}

# Setting:      show-toolbar = true
# Attribute:    show_toolbar = 1
function test_show_toolbar () {
    echo "Testing View > Toolbar."
    reset_saved_settings
    set_saved_setting show-toolbar false

    echo "Toolbar should be un-checked (no toolbar) ..."
    clear_all_attributes "$1"
    launch_evince "$1"

    echo "Toolbar should be checked (toolbar visible) ..."
    clear_all_attributes "$1"
    set_attribute "$1" show_toolbar 1
    launch_evince "$1"

    echo "Is the toolbar visible or not ...?"
    clear_all_attributes "$1"
    set_attribute "$1" $test_attr $test_value
    launch_evince "$1"

    select answer in visible not; do
        case $answer in
            not) echo "$pass"; break;;
            visible) echo "$fail"; break;;
        esac
    done
}

# Setting:      sidebar-page = links
# Attribute:    sidebar_page = thumbnails
# Values:       links, thumbnails, attachments, layers,
#               annotations, bookmarks
function test_sidebar_page () {
    echo "Testing Side Pane page."
    reset_saved_settings
    set_saved_setting sidebar-page bookmarks

    echo "Side Pane page should be set to Bookmarks ..."
    clear_all_attributes "$1"
    launch_evince "$1"

    echo "Side Pane page should be set to Thumbnails ..."
    clear_all_attributes "$1"
    set_attribute "$1" sidebar_page thumbnails
    launch_evince "$1"

    echo "Is the Side Pane page set to Bookmarks or Thumbnails ...?"
    clear_all_attributes "$1"
    set_attribute "$1" $test_attr $test_value
    launch_evince "$1"

    select answer in Bookmarks Thumbnails; do
        case $answer in
            Bookmarks) echo "$pass"; break;;
            Thumbnails) echo "$fail"; break;;
        esac
    done
}

# Setting:      sizebar-size = 132
# Attribute:    sidebar_size = 170
function test_sidebar_size () {
    echo "Testing Side Pane size."
    reset_saved_settings
    set_saved_setting sidebar-size 500

    echo "The Side Pane size should be big (500 px) ..."
    clear_all_attributes "$1"
    launch_evince "$1"

    echo "The Side Pane size should be small (170 px) ..."
    clear_all_attributes "$1"
    set_attribute "$1" sidebar_size 100
    launch_evince "$1"

    echo "Is the Side Pane size big or small ...?"
    clear_all_attributes "$1"
    set_attribute "$1" $test_attr $test_value
    launch_evince "$1"

    select answer in big small; do
        case $answer in
            big) echo "$pass"; break;;
            small) echo "$fail"; break;;
        esac
    done
}

# Setting:      sizing-mode = fit-width
# Attribute:    sizing_mode = fit-width
# Values:       best-fit, fit-width, free
function test_sizing_mode () {
    echo "Testing View > (sizing mode)."
    reset_saved_settings
    set_saved_setting sizing-mode best-fit

    echo "Best Fit should be checked (document fills window) ..."
    clear_all_attributes "$1"
    launch_evince "$1"

    echo "No sizing mode should be checked (document at zoom level) ..."
    clear_all_attributes "$1"
    set_attribute "$1" sizing_mode free
    launch_evince "$1"

    echo "Is Best Fit checked or un-checked ...?"
    clear_all_attributes "$1"
    set_attribute "$1" $test_attr $test_value
    launch_evince "$1"

    select answer in checked un-checked; do
        case $answer in
            checked) echo "$pass"; break;;
            un-checked) echo "$fail"; break;;
        esac
    done
}

# Setting:      window-ratio = (0.0, 0.0)
# Attribute:    none
function test_window_ratio () {
    # No attribute to test.
    return
}

# Setting:      zoom = 1.0
# Attribute:    zoom = 1.0
function test_zoom () {
    echo "Testing zoom level."
    reset_saved_settings
    set_saved_setting sizing-mode free
    set_saved_setting zoom 4.00

    echo "The zoom level should be 400 percent ..."
    clear_all_attributes "$1"
    launch_evince "$1"

    echo "The zoom level should be 50 percent ..."
    clear_all_attributes "$1"
    set_attribute "$1" sizing_mode free
    set_attribute "$1" zoom 0.50
    launch_evince "$1"

    echo "Is the zoom level 400 percent or some other value ...?"
    clear_all_attributes "$1"
    set_attribute "$1" sizing_mode free
    set_attribute "$1" $test_attr $test_value
    launch_evince "$1"

    select answer in 400 other; do
        case $answer in
            400) echo "$pass"; break;;
            other) echo "$fail"; break;;
        esac
    done
}

# Main body of script.

# Check for the script parameter.
if [ -z "$1" ]; then
    echo "Usage: $0 file"
    exit 1
fi
if [ ! -f "$1" ]; then
    echo "File not found: $1"
    exit 1
fi

# Run all tests.
test_continuous "$1"
test_dual_page "$1"
test_fullscreen "$1"
test_inverted_colors "$1"
test_show_sidebar "$1"
test_show_toolbar "$1"
test_sidebar_page "$1"
test_sidebar_size "$1"
test_sizing_mode "$1"
test_window_ratio "$1"
test_zoom "$1"

