aboutsummaryrefslogblamecommitdiffstats
path: root/datamaps/writer_test.go
blob: c6cf547910563da78f06f173523206d8a8203712 (plain) (tree)


































































































































































































                                                                                                                        
package datamaps

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"

	"github.com/tealeg/xlsx/v3"
)

var (
	// filesInMaster is a map of each filename from the header row of a master, mapped to its
	// column number
	filesInMaster = make(map[string]int)
)

func testSetup() (*Options, error) {
	// setup - we need the datamap in the test database
	_, err := setupDB("./testdata/test.db")

	if err != nil {
		fmt.Errorf("expected to be able to set up the database")
	}

	opts := Options{
		DBPath:           "./testdata/test.db",
		DMName:           "First Datamap",
		DMPath:           "./testdata/datamap_for_master_test.csv",
		ReturnName:       "Unnamed Return",
		MasterOutPutPath: "./testdata/",
		XLSXPath:         "./testdata/",
	}

	if err := DatamapToDB(&opts); err != nil {
		fmt.Errorf("unable to write datamap to database file because %v", err)
	}

	if err := ImportToDB(&opts); err != nil {
		fmt.Errorf("cannot read test XLSX files needed before exporting to master - %v", err)
	}
	return &opts, nil
}

func TestWriteMaster(t *testing.T) {

	opts, err := testSetup()
	if err != nil {
		t.Fatal(err)
	}

	defer func() {
		os.Remove(filepath.Join(opts.MasterOutPutPath, "master.xlsx"))
	}()

	defer func() {
		os.Remove("./testdata/test.db")
	}()

	if err := CreateMaster(opts); err != nil {
		t.Fatal(err)
	}

	var tests = []struct {
		key      string
		filename string
		sheet    string
		cellref  string
		value    string
	}{
		{"A Date", "test_template.xlsx", "Summary", "B2", "20/10/19"},
		{"A String", "test_template.xlsx", "Summary", "B3", "This is a string"},
		{"A String2", "test_template.xlsx", "Summary", "C3", "This is a string"},
		{"A String3", "test_template.xlsx", "Summary", "D3", "This is a string"},
		{"A Float", "test_template.xlsx", "Summary", "B4", "2.2"},
		{"An Integer", "test_template.xlsx", "Summary", "B5", "10"},
		{"A Date 1", "test_template.xlsx", "Another Sheet", "B3", "20/10/19"},
		{"A String 1", "test_template.xlsx", "Another Sheet", "B4", "This is a string"},
		{"A Float 1", "test_template.xlsx", "Another Sheet", "B5", "2.2"},
		{"An Integer 1", "test_template.xlsx", "Another Sheet", "B6", "10"},
		{"A Date 2", "test_template.xlsx", "Another Sheet", "D3", "21/10/19"},
		{"A String 2", "test_template.xlsx", "Another Sheet", "D4", "This is a string"},
		{"A Float 3", "test_template.xlsx", "Another Sheet", "D5", "3.2"},
		{"An Integer 3", "test_template.xlsx", "Another Sheet", "D6", "11"},
		{"A Ten Integer", "test_template.xlsx", "Introduction", "A1", "10"},
		{"A Test String", "test_template.xlsx", "Introduction", "C9", "Test Department"},
		{"A Vunt String", "test_template.xlsx", "Introduction", "C22", "VUNT"},
		{"A Parrot String", "test_template.xlsx", "Introduction", "J9", "Greedy Parrots"},

		{"A Date", "test_template.xlsm", "Summary", "B2", "20/10/19"},
		{"A String", "test_template.xlsm", "Summary", "B3", "This is a string"},
		{"A String2", "test_template.xlsm", "Summary", "C3", "This is a string"},
		{"A String3", "test_template.xlsm", "Summary", "D3", "This is a string"},
		{"A Float", "test_template.xlsm", "Summary", "B4", "2.2"},
		{"An Integer", "test_template.xlsm", "Summary", "B5", "10"},
		{"A Date 1", "test_template.xlsm", "Another Sheet", "B3", "20/10/19"},
		{"A String 1", "test_template.xlsm", "Another Sheet", "B4", "This is a string"},
		{"A Float 1", "test_template.xlsm", "Another Sheet", "B5", "2.2"},
		{"An Integer 1", "test_template.xlsm", "Another Sheet", "B6", "10"},
		{"A Date 2", "test_template.xlsm", "Another Sheet", "D3", "21/10/19"},
		{"A String 2", "test_template.xlsm", "Another Sheet", "D4", "This is a string"},
		{"A Float 3", "test_template.xlsm", "Another Sheet", "D5", "3.2"},
		{"An Integer 3", "test_template.xlsm", "Another Sheet", "D6", "11"},
		{"A Ten Integer", "test_template.xlsm", "Introduction", "A1", "10"},
		{"A Test String", "test_template.xlsm", "Introduction", "C9", "Test Department"},
		{"A Vunt String", "test_template.xlsm", "Introduction", "C22", "VUNT"},
		{"A Parrot String", "test_template.xlsm", "Introduction", "J9", "Greedy Parrots"},
	}

	// Regular testing of import
	// TODO fix date formatting
	for _, test := range tests {
		sql := fmt.Sprintf(`SELECT return_data.vFormatted FROM return_data, datamap_line 
		WHERE 
			(return_data.filename=%q 
				AND datamap_line.cellref=%q 
				AND datamap_line.sheet=%q
				AND return_data.dml_id=datamap_line.id);`, test.filename, test.cellref, test.sheet)

		got, err := exec.Command("sqlite3", opts.DBPath, sql).Output()
		if err != nil {
			t.Fatalf("something wrong %v", err)
		}
		gots := strings.TrimSuffix(string(got), "\n")
		if strings.Compare(gots, test.value) != 0 {
			t.Errorf("when testing the database, for key %s in file %s we expected %s but got %s", test.key,
				test.filename, test.value, gots)
		}
	}

	// Open the master and the target sheet
	master, err := xlsx.OpenFile("./testdata/master.xlsx")
	if err != nil {
		t.Fatal(err)
	}
	sheetName := "Master Data"
	sh, ok := master.Sheet[sheetName]
	if !ok {
		t.Errorf("Sheet named %s does not exist", sheetName)
	}
	defer sh.Close()

	err = sh.ForEachRow(rowVisitorTest)

	for _, tt := range tests {
		got, err := masterLookup(sh, tt.key, tt.filename)
		if err != nil {
			t.Fatal("Problem calling masterLookup()")
		}
		if got != tt.value {
			t.Errorf("when testing the master, for key %s we expected value %s in col %s - got %s",
				tt.key, tt.value, tt.filename, got)
		}
	}
}

func masterLookup(sheet *xlsx.Sheet, key string, filename string) (string, error) {
	var out string
	if err := sheet.ForEachRow(func(r *xlsx.Row) error {
		if r.GetCell(0).Value == key {
			out = r.GetCell(filesInMaster[filename]).Value
			return nil
		}
		return nil
	}); err != nil {
		return "", err
	}
	return out, nil
}

func cellVisitorTest(c *xlsx.Cell) error {
	seen := make(map[string]struct{})
	if _, ok := seen[c.Value]; !ok {
		if c.Value != "" {
			x, _ := c.GetCoordinates()
			filesInMaster[c.Value] = x
		}
		seen[c.Value] = struct{}{}
	}

	return nil
}

func rowVisitorTest(r *xlsx.Row) error {
	// TODO here we want to first find the file names from the header row,
	// then test that all key (from col 0) matches the value.

	if r.GetCoordinate() == 0 {
		r.ForEachCell(cellVisitorTest)
		return nil
	}
	return nil
}