package project_test import ( "os" "testing" "time" "geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/tests" "geeks-accelerator/oss/saas-starter-kit/example-project/internal/project" "github.com/google/go-cmp/cmp" "github.com/pkg/errors" ) var test *tests.Test // TestMain is the entry point for testing. func TestMain(m *testing.M) { os.Exit(testMain(m)) } func testMain(m *testing.M) int { test = tests.New() defer test.TearDown() return m.Run() } // TestProject validates the full set of CRUD operations on Project values. func TestProject(t *testing.T) { defer tests.Recover(t) t.Log("Given the need to work with Project records.") { t.Log("\tWhen handling a single Project.") { ctx := tests.Context() dbConn := test.MasterDB.Copy() defer dbConn.Close() np := project.NewProject{ Name: "Comic Books", Cost: 25, Quantity: 60, } p, err := project.Create(ctx, dbConn, &np, time.Now().UTC()) if err != nil { t.Fatalf("\t%s\tShould be able to create a project : %s.", tests.Failed, err) } t.Logf("\t%s\tShould be able to create a project.", tests.Success) savedP, err := project.Retrieve(ctx, dbConn, p.ID.Hex()) if err != nil { t.Fatalf("\t%s\tShould be able to retrieve project by ID: %s.", tests.Failed, err) } t.Logf("\t%s\tShould be able to retrieve project by ID.", tests.Success) if diff := cmp.Diff(p, savedP); diff != "" { t.Fatalf("\t%s\tShould get back the same project. Diff:\n%s", tests.Failed, diff) } t.Logf("\t%s\tShould get back the same project.", tests.Success) upd := project.UpdateProject{ Name: tests.StringPointer("Comics"), Cost: tests.IntPointer(50), Quantity: tests.IntPointer(40), } if err := project.Update(ctx, dbConn, p.ID.Hex(), upd, time.Now().UTC()); err != nil { t.Fatalf("\t%s\tShould be able to update project : %s.", tests.Failed, err) } t.Logf("\t%s\tShould be able to update project.", tests.Success) savedP, err = project.Retrieve(ctx, dbConn, p.ID.Hex()) if err != nil { t.Fatalf("\t%s\tShould be able to retrieve updated project : %s.", tests.Failed, err) } t.Logf("\t%s\tShould be able to retrieve updated project.", tests.Success) // Build a project matching what we expect to see. We just use the // modified time from the database. want := &project.Project{ ID: p.ID, Name: *upd.Name, Cost: *upd.Cost, Quantity: *upd.Quantity, DateCreated: p.DateCreated, DateModified: savedP.DateModified, } if diff := cmp.Diff(want, savedP); diff != "" { t.Fatalf("\t%s\tShould get back the same project. Diff:\n%s", tests.Failed, diff) } t.Logf("\t%s\tShould get back the same project.", tests.Success) upd = project.UpdateProject{ Name: tests.StringPointer("Graphic Novels"), } if err := project.Update(ctx, dbConn, p.ID.Hex(), upd, time.Now().UTC()); err != nil { t.Fatalf("\t%s\tShould be able to update just some fields of project : %s.", tests.Failed, err) } t.Logf("\t%s\tShould be able to update just some fields of project.", tests.Success) savedP, err = project.Retrieve(ctx, dbConn, p.ID.Hex()) if err != nil { t.Fatalf("\t%s\tShould be able to retrieve updated project : %s.", tests.Failed, err) } t.Logf("\t%s\tShould be able to retrieve updated project.", tests.Success) if savedP.Name != *upd.Name { t.Fatalf("\t%s\tShould be able to see updated Name field : got %q want %q.", tests.Failed, savedP.Name, *upd.Name) } else { t.Logf("\t%s\tShould be able to see updated Name field.", tests.Success) } if err := project.Delete(ctx, dbConn, p.ID.Hex()); err != nil { t.Fatalf("\t%s\tShould be able to delete project : %s.", tests.Failed, err) } t.Logf("\t%s\tShould be able to delete project.", tests.Success) savedP, err = project.Retrieve(ctx, dbConn, p.ID.Hex()) if errors.Cause(err) != project.ErrNotFound { t.Fatalf("\t%s\tShould NOT be able to retrieve deleted project : %s.", tests.Failed, err) } t.Logf("\t%s\tShould NOT be able to retrieve deleted project.", tests.Success) } } }