view cmd/sievemgr/internal/config/config_test.go @ 9:7ce77ceeaccc

Add documentation
author Guido Berhoerster <guido+sievemgr@berhoerster.name>
date Sat, 28 Nov 2020 23:44:45 +0100
parents 4dff4c3f0fbb
children 854167f55839
line wrap: on
line source

// Copyright (C) 2020 Guido Berhoerster <guido+sievemgr@berhoerster.name>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package config_test

import (
	"testing"

	"go.guido-berhoerster.org/sievemgr/cmd/sievemgr/internal/config"
)

const basicConfig = "\ufeff" + `account "foo"
    host "imap.example.net"
    user "bar@example.net" pass "53cRe7"
    default
account "local"
    host "localhost"
    port 2000
    insecure
    user "foo"
    pass "s3cR3Et"
account "bar" host "imap.example.com" user "bar@example.com" pass "53cRe7"
`

func TestBasicFunctionality(t *testing.T) {
	var conf config.Configuration
	if err := config.Parse([]byte(basicConfig), &conf); err != nil {
		t.Fatalf("failed to parse basic config file: %s", err)
	}
	if n := len(conf.Accounts); n != 3 {
		t.Fatalf("invalid number of parsed accounts, expected 2, got %d", n)
	}
	if conf.Accounts[0].Name != "foo" ||
		conf.Accounts[0].Host != "imap.example.net" ||
		conf.Accounts[0].Port != "4190" ||
		conf.Accounts[0].User != "bar@example.net" ||
		conf.Accounts[0].Password != "53cRe7" ||
		conf.Accounts[0].Insecure {
		t.Fatalf(`failed to parse account, expected &main.Account{Name:"foo", Host:"imap.example.net", Port:"4190", User:"bar@example.net", Password:"53cRe7", Insecure:false}, got %#+v`, conf.Accounts[0])
	}
	if conf.Default == nil {
		t.Fatalf("default account not found")
	}
	if conf.Default != conf.Accounts[0] {
		t.Fatalf("wrong default account, expected \"default\", got %q", conf.Default.Name)
	}
}

const invalidBOMConfig = "\ufeff\ufeff" + `account "foo" host "imap.example.net" user "bar@example.net" pass "53cRe7" default`

func TestInvalidBOM(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(invalidBOMConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to BOM not at the beginning but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const invalidUTF8Config = `account "foo"` + "\xff" + ` host "imap.example.net" user "bar@example.net" pass "53cRe7" default`

func TestInvalidUTF8(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(invalidUTF8Config), &conf)
	if err == nil {
		t.Fatalf("expected error due to invalid UTF-8 but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const nulByteConfig = `account "foo` + "\x00" + `" host "imap.example.net" user "bar@example.net" pass "53cRe7" default`

func TestNulByte(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(nulByteConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to nul byte but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const unexpectedRuneConfig = `account "foo" host "imap.example.net" user "bar@example.net" pass "53cRe7" _in_valid default`

func TestInvalidIdentifier(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(unexpectedRuneConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to unexpected rune but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const unknownIdentifierConfig = `account "foo" host "imap.example.net" user "bar@example.net" pass "53cRe7" invalid default`

func TestUnknownIdentifier(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(unknownIdentifierConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to unknown identifier but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const missingWhitespaceConfig = `account "foo" host "imap.example.net" port 2000default user "bar@example.net" pass "53cRe7"`

func TestMissingSpace(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(missingWhitespaceConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to missing whitespace between tokens but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const missingNameConfig = `account host "imap.example.net" user "bar@example.net" pass "53cRe7" default`

func TestMissingName(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(missingNameConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to missing account name but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const invalidTypeConfig = `account 1234 host "imap.example.net" user "bar@example.net" pass "53cRe7"`

func TestInvalidType(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(invalidTypeConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to invalid type but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const unterminatedStringConfig = `account "foo" host "imap.example.net" user "bar@example.net" pass "53cRe7
account "bar" host "imap.example.com" user "bar@example.com" pass "53cRe7"
`

func TestUnterminatedString(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(unterminatedStringConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to an unterminated string but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const unexpectedEOFConfig = `account "foo" host "imap.example.net" user "bar@example.net" pass `

func TestUnexpectedEOF(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(unexpectedEOFConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to an unterminated string but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const missingHostConfig = `account "foo" user "bar@example.net" pass "53cRe7"`

func TestMissingHost(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(missingHostConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to missing host but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}

const missingUserConfig = `account "foo" host "imap.example.net" user "" pass "53cRe7"`

func TestMissingUser(t *testing.T) {
	var conf config.Configuration
	err := config.Parse([]byte(missingUserConfig), &conf)
	if err == nil {
		t.Fatalf("expected error due to missing user but succeeded")
	}
	if _, ok := err.(*config.ParserError); !ok {
		t.Fatalf("expected config.ParserError, got %T (%q)", err,
			err)
	}
	t.Logf("reported error: %s", err)
}