#!/usr/bin/env bash
# pass update - Password Store Extension (https://www.passwordstore.org/)
# Copyright (C) 2017 Alexandre PUJOL <alexandre@pujol.io>.
#
#    This program 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 3 of the License, or
#    (at your option) any later version.
#
#    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
#

# Test units suite

#
# pass config
#
PASS="$(which pass)"
export PASSWORD_STORE_ENABLE_EXTENSIONS=true
export PASSWORD_STORE_EXTENSIONS_DIR="../"
export PASSWORD_STORE_DIR="password-store"
_pass() {
	${PASS} "$@"
	return $?
}
pass_populate() {
	_pass init "$@"
	_pass generate Website/user1
	_pass generate Website/user2
	return $?
}

#
# Common colors and functions
#
red='\e[0;31m'
green='\e[0;32m'
yellow='\e[0;33m'
blue='\e[0;34m'
bold='\e[1m'
Bred='\e[1;31m'
Bgreen='\e[1;32m'
Byellow='\e[1;33m'
Bblue='\e[1;34m'
reset='\e[0m'
title() { echo -e "${Bblue}::${reset} ${bold}${*}${reset}"; }
alert() { echo -e " $${Byellow}(*)${reset} ${*}"; }
warn() { echo -e " ${Byellow}[W]${reset}${bold} Warning :${reset} ${*}"; }
success() { echo -e " ${Bgreen}(*)${reset} ${green}${*}${reset}"; }
error() { echo -e " ${Bred}[*]${reset}${bold} Error :${reset} ${*}"; }
fail() { echo -e " ${Bred}[*]${reset} ${red}${*}${reset}"; }
die() { error "${@}" && exit 1; }
notice() { echo; title "${@}"; echo; }
test_xclip() {
	echo "$RANDOM" | xclip -i &> /dev/null
	[ $? = 0 ] || XCLIP=1
}

#
# Test suite config
#
GLOBAL_RESULT=0
XCLIP=0
test_xclip # xclip needs a X server, disable xclip tests when running on a server

typeset -A results
tests=(pass-update pass-update-multiple pass-update-opt)
[ $XCLIP = 0 ] && tests+=(pass-update-clip)

#
# GnuPG Conf.
#
# Note: the assumption is the test keys are unencrypted.
export GNUPGHOME="gnupg/"
chmod 700 "$GNUPGHOME"
KEY1="D4C78DB7920E1E27F5416B81CC9DB947CF90C77B"
KEY2="70BD448330ACF0653645B8F2B4DDBFF0D774A374"
KEY3="62EBE74BE834C2EC71E6414595C4B715EB7D54A8"
KEY4="9378267629F989A0E96677B7976DD3D6E4691410"
KEY5="4D2AFBDE67C60F5999D143AFA6E073D439E5020C"


#
# Test Suite
#
notice "Loading test suite"
mkdir -p "$PASSWORD_STORE_DIR"
[[ ! -e $PASS ]] && die "Could not find pass command"
[[ -e "$PASSWORD_STORE_DIR/.gpg-id" ]] || pass_populate "$KEY1"
_pass

pass_update() {
	notice "Test - updating password."
	_pass update Website/user1 --force
	test $? = 0 && results[pass-update]=SUCCESS

	if [ $XCLIP = 0 ]; then
		notice "Test - updating password with clip."
		_pass update Website/user2 --clip --force
		test $? = 0 && results[pass-update-clip]=SUCCESS
	fi

	notice "Test - updating more than one password"
	_pass update Website/user1 Website/user2 --force
	test $? = 0 && results[pass-update-multiple]=SUCCESS

	notice "Test - Bad options"
	res=0
	_pass update  &> /dev/null
	test $? = 1 || res=1
	_pass update Website/user  &> /dev/null
	test $? = 1 || res=1
	_pass update --unknown-option  &> /dev/null
	test $? = 1 || res=1
	_pass update --help  &> /dev/null
	test $? = 0 || res=1
	test $res = 0 && results[pass-update-opt]=SUCCESS
}

pass_update


#
# Units Test Results
#
notice "Test Results"
for t in ${tests[@]}; do
	res=${results[$t]:-FAIL}
	if [[ "$res" == "SUCCESS" ]]; then
		success "$t\t$res"
	else
		fail "$t\t$res"
		GLOBAL_RESULT=1
	fi
done

success "Done. You can remove temporary leftovers from ${PASSWORD_STORE_DIR}/"

unset PASSWORD_STORE_ENABLE_EXTENSIONS
unset PASSWORD_STORE_EXTENSIONS_DIR
unset PASSWORD_STORE_DIR
unset PASSWORD_STORE_SIGNING_KEY

[ $GLOBAL_RESULT = 0 ] && {
	success "Tests passed"
} || {
	error "Tests failed"
}

exit $GLOBAL_RESULT
