func TestDeletePOST(t *testing.T) { db := mem.NewDB() u, _, err := user.Create(db, "username", "password") if err != nil { t.Fatalf("user.Create error: %v", err) } e := &models.Event{ Id: db.NewID().String(), OwnerId: u.Id, Name: "event name", Data: map[string]interface{}{ "sensor": 45.3, }, } if err := db.Save(e); err != nil { t.Fatalf("db.Save error: %v", err) } s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if strings.Contains(r.RequestURI, "/records/delete/") { records.DeletePOST(user.NewContext(context.Background(), u), w, r, db, services.NewTestLogger(t)) } records.QueryGET(user.NewContext(context.Background(), u), w, r, db, services.NewTestLogger(t)) })) p := s.URL + "/records/delete/?" + url.Values{ "kind": []string{"event"}, "id": []string{e.Id}, }.Encode() resp, err := http.Post(p, "", new(bytes.Buffer)) if err != nil { t.Fatalf("http.Post error: %v", err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatalf("ioutil.ReadAll error: %v", err) } t.Logf("resp.Body:\n%s", body) if got, want := db.PopulateByID(e), data.ErrNotFound; got != want { t.Fatalf("db.PopulateByID: got %v, want %v", got, want) } }
func TestNewGET(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { records.NewGET(context.Background(), w, r, mem.NewDB(), services.NewTestLogger(t)) })) resp, err := http.Get(s.URL) if err != nil { t.Fatalf("http.Get error: %v", err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatalf("ioutil.ReadAll error: %v", err) } t.Logf("resp.Body:\n%s", body) for name := range models.Metis { if name == "user" { continue } if got, want := bytes.Contains(body, []byte(name)), true; got != want { t.Errorf("strings.Contains(out, %q): got %t, want %t", name, got, want) } } }
func BenchmarkRecordPostEvent(b *testing.B) { db := mem.NewDB() u, _, err := user.Create(db, "username", "password") if err != nil { b.Fatalf("user.Create error: %v", err) } ctx := user.NewContext(context.Background(), u) logger := services.NewTestLogger(b) for i := 0; i < b.N; i++ { rec := httptest.NewRecorder() req, err := http.NewRequest( "POST", "http://www.elos.pw/record/?"+url.Values{ "kind": []string{models.EventKind.String()}, }.Encode(), bytes.NewBuffer( []byte(`{ "name": "event name", "data": { "sensor1": 34, "sensor2": 4.3 }, "owner_id": "`+u.ID().String()+`" }`), )) if err != nil { b.Fatalf("http.NewRequest error: %v", err) } routes.RecordPOST(ctx, rec, req, logger, db) } }
func TestCreateGET(t *testing.T) { adb, dbc, ac, closers, err := records_test.ClientsFromState(data.State{}) defer func() { records_test.CloseAll(closers) }() wui := records.NewWebUI(adb, ac) s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { records.CreateGET(context.Background(), w, r, db, services.NewTestLogger(t), wui) })) p := s.URL + "?" + url.Values{"kind": []string{"event"}}.Encode() resp, err := http.Get(p) if err != nil { t.Fatalf("http.Get(%q) error: %v", p, err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatalf("ioutil.ReadAll error: %v", err) } t.Logf("resp.Body:\n%s", body) if got, want := bytes.Contains(body, []byte(`event`)), true; got != want { t.Fatalf("bytes.Contains(body, %q): got %t, want %t", "event", got, want) } }
func TestEditGET(t *testing.T) { db := mem.NewDB() u, _, err := user.Create(db, "username", "password") if err != nil { t.Fatalf("user.Create error: %v", err) } e := &models.Event{ Id: db.NewID().String(), OwnerId: u.Id, Name: "old name", Data: map[string]interface{}{ "sensor": 4, }, } if err := db.Save(e); err != nil { t.Fatalf("db.Save error: %v", err) } s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { records.EditGET(user.NewContext(context.Background(), u), w, r, db, services.NewTestLogger(t)) })) p := s.URL + "?" + url.Values{ "kind": []string{"event"}, "id": []string{e.Id}, }.Encode() resp, err := http.Get(p) if err != nil { t.Fatalf("http.Get(%q) error: %v", p, err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatalf("ioutil.ReadAll error: %v", err) } t.Logf("resp.Body:\n%s", body) if got, want := bytes.Contains(body, []byte(`event`)), true; got != want { t.Fatalf("bytes.Contains(body, %q): got %t, want %t", "event", got, want) } if got, want := bytes.Contains(body, []byte(`old name`)), true; got != want { t.Fatalf("bytes.Contains(body, %q): got %t, want %t", "old name", got, want) } if got, want := bytes.Contains(body, []byte(`/records/view/?kind=event&id=3`)), true; got != want { t.Fatalf("bytes.Contains(body, %q): got %t, want %t", `/records/view/?kind=event&id=3`, got, want) } }
func TestRecordsNewGET(t *testing.T) { ctx := context.Background() db := mem.NewDB() logger := services.NewTestLogger(t) s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx, ok := Authenticate(ctx, w, r, logger, db) if !ok { t.Fatal("authentication failed") } Records.NewGET(ctx, w, r, db, logger) })) defer s.Close() _, _, err := user.Create(db, "username", "password") if err != nil { t.Fatal(err) } c := new(http.Client) req, err := http.NewRequest("GET", s.URL, nil) if err != nil { t.Fatal(err) } req.SetBasicAuth("username", "password") resp, err := c.Do(req) if err != nil { t.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } t.Logf("Body:\n%s", body) doc := string(body) contains := map[string]bool{ "user": false, "event": true, "New": true, } for c, want := range contains { if got := strings.Contains(doc, c); got != want { t.Fatalf("strings.Contains(%q): got %t, want %t", c, got, want) } } }
func TestRecordsQueryGET(t *testing.T) { ctx := context.Background() db := mem.NewDB() logger := services.NewTestLogger(t) s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx, ok := Authenticate(ctx, w, r, logger, db) if !ok { t.Fatal("authentication failed") } Records.QueryGET(ctx, w, r, db, logger) })) defer s.Close() _, _, err := user.Create(db, "username", "password") if err != nil { t.Fatal(err) } c := new(http.Client) req, err := http.NewRequest("GET", s.URL+"?"+url.Values{ "query/Kind": []string{"credential"}, }.Encode(), nil) if err != nil { t.Fatal(err) } req.SetBasicAuth("username", "password") resp, err := c.Do(req) if err != nil { t.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } t.Logf("Body:\n%s", body) doc := string(body) if got, want := strings.Contains(doc, "username"), true; got != want { t.Fatalf("strings.Contains(doc, \"username\"): got %t, want %t", got, want) } if got, want := strings.Contains(doc, "password"), true; got != want { t.Fatalf("strings.Contains(doc, \"password\"): got %t, want %t", got, want) } }
func TestAuthenticateQueryParams(t *testing.T) { ctx := context.Background() db := mem.NewDB() logger := services.NewTestLogger(t) var userContext context.Context var authed bool s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { userContext, authed = routes.Authenticate(ctx, w, r, logger, db) if authed { w.WriteHeader(http.StatusOK) } })) defer s.Close() u, _, err := user.Create(db, "username", "password") if err != nil { t.Fatalf("user.Create(db, \"username\", \"password\") error: %s", err) } client := new(http.Client) req, err := http.NewRequest("GET", s.URL, new(bytes.Buffer)) if err != nil { t.Fatalf("http.NewRequest error: %s", err) } client.Do(req) if got, want := authed, false; got != want { t.Fatalf("authed: got %t, want %t", got, want) } req, err = http.NewRequest("GET", s.URL+"?public=username&private=password", new(bytes.Buffer)) if err != nil { t.Fatalf("http.NewRequest error: %s", err) } client.Do(req) if got, want := authed, true; got != want { t.Fatalf("authed: got %t, want %t") } authedU, ok := user.FromContext(userContext) if got, want := ok, true; got != want { t.Fatalf("_, ok := user.FromContext: got %t, want %t") } if got, want := data.Equivalent(authedU, u), true; got != want { t.Errorf("data.Equivalent(authedU, u): got %t, want %t", got, want) } }
func testInstance(t *testing.T, ctx context.Context) (data.DB, *gaia.Gaia, *httptest.Server) { db := mem.NewDB() g := gaia.New( ctx, &gaia.Middleware{}, &gaia.Services{ Logger: services.NewTestLogger(t), DB: db, SMSCommandSessions: services.NewSMSMux(), WebCommandSessions: services.NewWebMux(), }, ) s := httptest.NewServer(g) return db, g, s }
func TestAuthenticatePostForm(t *testing.T) { ctx := context.Background() db := mem.NewDB() logger := services.NewTestLogger(t) var userContext context.Context var authed bool s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { userContext, authed = routes.Authenticate(ctx, w, r, logger, db) if authed { w.WriteHeader(http.StatusOK) } })) defer s.Close() u, _, err := user.Create(db, "username", "password") if err != nil { t.Fatalf("user.Create(db, \"username\", \"password\") error: %s", err) } client := new(http.Client) client.PostForm(s.URL, url.Values{ "public": []string{"username"}, "private": []string{"password"}, }) if got, want := authed, true; got != want { t.Fatalf("authed: got %t, want %t", got, want) } authedU, ok := user.FromContext(userContext) if got, want := ok, true; got != want { t.Fatalf("_, ok := user.FromContext: got %t, want %t", got, want) } if got, want := data.Equivalent(authedU, u), true; got != want { t.Fatal("data.Equivalent(authedU, u): got %t ,want %t", got, want) } }
func TestLoginPOST(t *testing.T) { ctx := context.Background() db := mem.NewDB() logger := services.NewTestLogger(t) m := http.NewServeMux() m.Handle("/login/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx, ok := routes.Authenticate(ctx, w, r, logger, db) if !ok { t.Fatal("bad authentication") } routes.LoginPOST(ctx, w, r, db, logger) })) m.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusAccepted) })) s := httptest.NewServer(http.HandlerFunc(m.ServeHTTP)) defer s.Close() _, _, err := user.Create(db, "username", "password") if err != nil { t.Fatalf("user.Create(db, \"username\", \"password\") error: %s", err) } req, err := http.NewRequest("GET", s.URL+"/login/", new(bytes.Buffer)) if err != nil { t.Fatalf("http.NewRequest error: %s", err) } req.SetBasicAuth("username", "password") jar, err := cookiejar.New(new(cookiejar.Options)) if err != nil { t.Fatalf("cookiejar.New error: %s", err) } client := &http.Client{ Jar: jar, } resp, err := client.Do(req) if err != nil { t.Fatalf("error posting to LoginPOST: %s", err) } t.Logf("Response:\n\t%v", resp) if got, want := resp.StatusCode, http.StatusAccepted; got != want { t.Errorf("resp.StatusCode: got %d, want %d", got, want) } iter, err := db.Query(models.SessionKind).Execute() if err != nil { t.Fatalf("db.Query(models.SessionKind).Execute(): %s", err) } seshes := mem.Slice(iter, func() data.Record { return new(models.Session) }) if got, want := len(seshes), 1; got != want { t.Fatalf("len(seshes): got %d, want %d", got, want) } uri, err := url.Parse(s.URL) if err != nil { t.Fatalf("url.Prase(s.URL) error: %s", err) } t.Logf("URL: %s", uri) cookies := jar.Cookies(uri) if got, want := len(cookies), 1; got != want { t.Fatalf("len(cookies): got %d, want %d", got, want) } if got, want := cookies[0].Value, seshes[0].(*models.Session).Token; got != want { t.Errorf("cookies[0].Value: got %s, want %s", got, want) } }
// TestEventPOST tests a POST request to the '/event/' endpoint. // in the happy case (i.e., all parameters present). // We verify: // * The event's name // * The event's data // * The event's tags func TestEventPOST(t *testing.T) { ctx := context.Background() db := mem.NewDB() logger := services.NewTestLogger(t) s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx, ok := routes.Authenticate(ctx, w, r, logger, db) if !ok { t.Error("routes.Authenticate failed") } routes.EventPOST(ctx, w, r, db, logger) })) defer s.Close() _, _, err := user.Create(db, "username", "password") if err != nil { t.Fatalf("user.Create(db, \"username\", \"password\") error: %s", err) } u := s.URL + "?" + url.Values{ "tags": []string{"tag1", "tag2"}, }.Encode() body := map[string]interface{}{ "name": "event name", "time": time.Now(), "data": map[string]interface{}{ "arbitrary": []string{"data"}, "here": 1.0, "foo": map[string]interface{}{ "bar": "there", }, }, } b, err := json.Marshal(body) if err != nil { t.Fatal("json.Marshal(body) error: %s", err) } req, err := http.NewRequest("POST", u, bytes.NewBuffer(b)) req.SetBasicAuth("username", "password") client := new(http.Client) resp, err := client.Do(req) if err != nil { t.Fatalf("client.Do(req) error: %s", err) } defer resp.Body.Close() if got, want := resp.StatusCode, http.StatusCreated; got != want { t.Fatalf("resp.StatusCode: got %d, want %d", got, want) } b, err = ioutil.ReadAll(resp.Body) if err != nil { t.Fatalf("ioutil.ReadAll(resp.Body) error: %s", err) } e := new(models.Event) if err := json.Unmarshal(b, e); err != nil { t.Fatalf("json.Unmarshal(b, e) error: %s", err) } t.Logf("Event:\n\t%v", e) if got, want := e.Name, "event name"; got != want { t.Errorf("e.Name: got %q, want %q", got, want) } if got, want := e.Data["foo"].(map[string]interface{})["bar"], "there"; got != want { t.Errorf("e.Data[\"foo\"][\"bar\"]: got %q, want %q", got, want) } if got, want := len(e.TagsIds), 2; got != want { t.Fatalf("len(e.TagsIds): got %d, want %d", got, want) } tags, err := e.Tags(db) if err != nil { t.Fatalf("e.Tags(db) error: %s", err) } if got, want := len(tags), 2; got != want { t.Fatalf("len(tags): got %d, want %d", got, want) } if got, want := tags[0].Name, "tag1"; got != want { t.Errorf("tags[0].Name: got %q, want %q", got, want) } if got, want := tags[1].Name, "tag2"; got != want { t.Errorf("tags[1].Name: got %q, want %q", got, want) } }
// --- TestAuthenticateSession {{{ func TestAuthenticateSession(t *testing.T) { ctx := context.Background() db := mem.NewDB() logger := services.NewTestLogger(t) var userContext context.Context var authed bool s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { userContext, authed = routes.Authenticate(ctx, w, r, logger, db) if authed { w.WriteHeader(http.StatusOK) } })) defer s.Close() u, _, err := user.Create(db, "username", "password") if err != nil { t.Fatalf("user.Create(db, \"username\", \"password\") error: %s", err) } client := new(http.Client) req, err := http.NewRequest("GET", s.URL, new(bytes.Buffer)) if err != nil { t.Fatalf("http.NewRequest error: %s", err) } req.AddCookie(&http.Cookie{ Name: "elos-session-token", Value: "garbage", }) client.Do(req) if got, want := authed, false; got != want { t.Errorf("authed: got %t, want %t", got, want) } sesh := models.NewSessionForUser(u) sesh.SetID(db.NewID()) if err := db.Save(sesh); err != nil { t.Fatalf("db.Save(sesh) error: %s", err) } req, err = http.NewRequest("GET", s.URL, new(bytes.Buffer)) if err != nil { t.Fatalf("http.NewRequest error: %s", err) } req.AddCookie(&http.Cookie{ Name: "elos-session-token", Value: sesh.Token, }) client.Do(req) if got, want := authed, true; got != want { t.Fatalf("authed: got %t, want %t", got, want) } authedU, ok := user.FromContext(userContext) if got, want := ok, true; got != want { t.Fatalf("_, ok := user.FromContext: got %t, want %t", got, want) } if got, want := data.Equivalent(authedU, u), true; got != want { t.Errorf("data.Equivalent(authedU, u): got %t, want %t", got, want) } }
func TestCommandSMS(t *testing.T) { db := mem.NewDB() sms := newMockSMS() mux := services.NewSMSMux() ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() go mux.Start(ctx, db, sms) ctx, cancelContext := context.WithCancel(context.Background()) defer cancelContext() g := gaia.New( ctx, &gaia.Middleware{}, &gaia.Services{ Logger: services.NewTestLogger(t), DB: db, SMSCommandSessions: mux, WebCommandSessions: services.NewWebMux(), }, ) s := httptest.NewServer(g) defer s.Close() u, _ := testUser(t, db) t.Log("Creating profile") p := models.NewProfile() p.SetID(db.NewID()) phone := "650 123 4567" p.Phone = phone p.SetOwner(u) if err := db.Save(p); err != nil { t.Fatal(err) } t.Log("Created") messageBody := "todo" params := url.Values{} params.Set("To", phone) // /command/ ignores this, twilio sends it though params.Set("From", phone) params.Set("Body", messageBody) url := s.URL + "/command/sms/?" + params.Encode() t.Logf("Constructed URL: %s", url) req, err := http.NewRequest("POST", url, nil) if err != nil { t.Fatal(err) } resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } t.Logf("Code: %d", resp.StatusCode) t.Logf("Body:\n%s", body) if resp.StatusCode != http.StatusNoContent { t.Fatalf("Expected status code of %d", http.StatusNoContent) } select { case m := <-sms.bus: t.Logf("Message:\n%+v", m) if !strings.Contains(m.body, "elos") { t.Fatal("The message should have almost certainly contained the word elos") } case <-time.After(1 * time.Second): t.Fatal("Timed out waiting for sms message") } }
func TestCommandSMSInput(t *testing.T) { db := mem.NewDB() sms := newMockSMS() mux := services.NewSMSMux() ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() go mux.Start(ctx, db, sms) ctx, cancelContext := context.WithCancel(context.Background()) defer cancelContext() g := gaia.New( ctx, &gaia.Middleware{}, &gaia.Services{ Logger: services.NewTestLogger(t), DB: db, SMSCommandSessions: mux, WebCommandSessions: services.NewWebMux(), }, ) s := httptest.NewServer(g) defer s.Close() u, _ := testUser(t, db) t.Log("Creating profile") p := models.NewProfile() p.SetID(db.NewID()) phone := "650 123 4567" p.Phone = phone p.SetOwner(u) if err := db.Save(p); err != nil { t.Fatal(err) } t.Log("Created") messageBody := "todo new" fakeSMS(t, s, phone, phone, messageBody) select { case m := <-sms.bus: t.Logf("Message:\n%+v", m) if !strings.Contains(m.body, "Name") { t.Fatal("The message should have asked for name of task") } case <-time.After(1 * time.Second): t.Fatal("Timed out waiting for sms message") } taskName := "task name" // for the name fakeSMS(t, s, phone, phone, taskName) select { case m := <-sms.bus: t.Logf("Message:\n%+v", m) if !strings.Contains(m.body, "deadline") { t.Fatal("The message should have asked if it had a deadline") } case <-time.After(1 * time.Second): t.Fatal("Timed out waiting for sms message") } fakeSMS(t, s, phone, phone, "n") // no deadline select { case m := <-sms.bus: t.Logf("Message:\n%+v", m) if !strings.Contains(m.body, "prerequisites") { t.Fatal("The message should have asked if it had a prereqs") } case <-time.After(1 * time.Second): t.Fatal("Timed out waiting for sms message") } fakeSMS(t, s, phone, phone, "n") // no prereqs select { case m := <-sms.bus: t.Logf("Message:\n%+v", m) if !strings.Contains(m.body, "created") { t.Fatal("Should have indicated task was created") } case <-time.After(1 * time.Second): t.Fatal("Timed out waiting for sms message") } task := models.NewTask() // ensure the task exists if err := db.PopulateByField("name", taskName, task); err != nil { t.Fatal(err) } t.Logf("Task:\n%+v", task) }
func TestRecordsEditGET(t *testing.T) { ctx := context.Background() db := mem.NewDB() logger := services.NewTestLogger(t) s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ctx, ok := Authenticate(ctx, w, r, logger, db) if !ok { t.Fatal("authentication failed") } Records.EditGET(ctx, w, r, db, logger) })) defer s.Close() u, _, err := user.Create(db, "username", "password") if err != nil { t.Fatal(err) } e := new(models.Event) e.SetID(db.NewID()) e.SetOwner(u) e.Name = "eventname" if err := db.Save(e); err != nil { t.Fatal("db.Save(e) error: %s", err) } c := new(http.Client) req, err := http.NewRequest("GET", s.URL+"?"+url.Values{ "kind": []string{string(models.EventKind)}, "id": []string{e.Id}, }.Encode(), nil) if err != nil { t.Fatal(err) } req.SetBasicAuth("username", "password") resp, err := c.Do(req) if err != nil { t.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatal(err) } t.Logf("Body:\n%s", body) doc := string(body) contains := map[string]bool{ "eventname": true, "name": true, } for c, want := range contains { if got := strings.Contains(doc, c); got != want { t.Fatalf("strings.Contains(%q): got %t, want %t", c, got, want) } } }
// --- 'elos setup' (context: need a new account) {{{ func TestSetupNewUser(t *testing.T) { f, err := ioutil.TempFile("", "conf") if err != nil { t.Fatal(err) } defer f.Close() db := mem.NewDB() dbc, closers, err := access.NewTestDB(db) if err != nil { t.Fatalf("access.NewTestDB error: %v", err) } defer func(cs []io.Closer) { for _, c := range cs { c.Close() } }(closers) authc, closers, err := auth.NewTestAuth(db) if err != nil { t.Fatalf("access.NewTestDB error: %v", err) } defer func(cs []io.Closer) { for _, c := range cs { c.Close() } }(closers) webui, conn, err := records.WebUIBothLocal(dbc, authc) if err != nil { t.Fatalf("records.WebUIBothLocal error: %v", err) } defer conn.Close() g := gaia.New( context.Background(), &gaia.Middleware{}, &gaia.Services{ SMSCommandSessions: services.NewSMSMux(), Logger: services.NewTestLogger(t), DB: db, WebUIClient: webui, }, ) s := httptest.NewServer(g) defer s.Close() ui, conf, c := newMockSetupCommand(t) conf.Path = f.Name() // no already account, then username input and password input ui.InputReader = bytes.NewBufferString(fmt.Sprintf("%s\nn\npublic\nprivate\n", s.URL)) t.Log("running: `elos setup`") code := c.Run([]string{}) t.Log("command `setup` terminated") t.Log("Reading outputs") errput := ui.ErrorWriter.String() output := ui.OutputWriter.String() t.Logf("Error output:\n%s", errput) t.Logf("Output:\n%s", output) // verify there were no errors if errput != "" { t.Fatalf("Expected no error output, got: %s", errput) } // verify success if code != 0 { t.Fatalf("Expected successful exit code along with empty error output.") } // verify some of the output if !strings.Contains(output, "account") { t.Fatalf("Output should have contained a 'account' for saying something about an account") } i, err := db.Query(data.Kind(models.Kind_CREDENTIAL.String())).Select(data.AttrMap{ "public": "public", "private": "private", }).Execute() if err != nil { t.Fatal(err) } cred := new(models.Credential) if ok := i.Next(cred); !ok { t.Fatal("no credentials found") } if got, want := cred.OwnerId, "1"; got != want { t.Fatalf("cred.OwnerId: got %q, want %q", got, want) } // verify conf was changed if got, want := conf.UserID, "1"; got != want { t.Fatalf("conf.UserID: got %q, want %q", got, want) } if conf.PublicCredential != "public" { t.Fatalf("public credential should be: public") } if conf.PrivateCredential != "private" { t.Fatalf("private credential should be: private") } }
func TestCommandWeb(t *testing.T) { db := mem.NewDB() sms := newMockSMS() smsMux := services.NewSMSMux() webMux := services.NewWebMux() ctx := context.Background() ctx, cancel := context.WithCancel(ctx) defer cancel() go smsMux.Start(ctx, db, sms) go webMux.Start(ctx, db) ctx, cancelContext := context.WithCancel(context.Background()) defer cancelContext() g := gaia.New( ctx, &gaia.Middleware{}, &gaia.Services{ Logger: services.NewTestLogger(t), DB: db, SMSCommandSessions: smsMux, WebCommandSessions: webMux, }, ) s := httptest.NewServer(g) defer s.Close() _, cred := testUser(t, db) serverURL := s.URL origin := serverURL wsURL := strings.Replace(serverURL, "http", "ws", 1) params := url.Values{} params.Set("public", cred.Public) params.Set("private", cred.Private) wsURL += "/command/web/?" + params.Encode() t.Logf("Constructed URL: %s", wsURL) t.Log("Opening websocket") ws, err := websocket.Dial(wsURL, "", origin) if err != nil { t.Fatal(err) } defer ws.Close() t.Log("Websocket openened") messageBody := "todo" // Sending a message t.Logf("Sending message: %s", messageBody) websocket.Message.Send(ws, messageBody) t.Logf("Sent") t.Log("Recieving a message") var received string websocket.Message.Receive(ws, &received) t.Logf("Recieved message: %s", received) t.Log("Verifying the response contained the word 'elos'") if !strings.Contains(received, "elos") { t.Fatal("The message should have almost certainly contained the word elos") } t.Log("Verified") }
func TestViewGET(t *testing.T) { db := mem.WithData(map[data.Kind][]data.Record{ models.UserKind: { &models.User{ Id: "1", CredentialsIds: []string{"2"}, }, }, models.CredentialKind: { &models.Credential{ Id: "2", OwnerId: "1", Spec: "password", Public: "public", Private: "private", }, }, }) s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { records.ViewGET(user.NewContext(context.Background(), &models.User{Id: "1"}), w, r, db, services.NewTestLogger(t)) })) p := s.URL + "?" + url.Values{ "kind": []string{"credential"}, "id": []string{"2"}, }.Encode() resp, err := http.Get(p) if err != nil { t.Fatalf("http.Get(%q) error: %v", err) } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatalf("ioutil.ReadAll error: %v", err) } body := string(b) t.Logf("resp.Body:\n%s", body) contents := map[string]bool{ "credential": true, "public": true, "password": true, "owner": true, "/records/edit/?kind=credential&id=2": true, "user": false, } for content, want := range contents { if got := strings.Contains(body, content); got != want { t.Fatalf("strings.Contains(body, %q): got %t, want %t", content, got, want) } } }
func TestQueryGET(t *testing.T) { db := mem.WithData(map[data.Kind][]data.Record{ models.UserKind: []data.Record{ &models.User{ Id: "1", CredentialsIds: []string{"2"}, }, &models.User{ Id: "2", }, }, models.CredentialKind: []data.Record{ &models.Credential{ Id: "3", CreatedAt: time.Now(), Spec: "password", Public: "username", Private: "password", }, }, models.EventKind: []data.Record{ &models.Event{ Id: "4", OwnerId: "1", Name: "event 1", }, &models.Event{ Id: "5", OwnerId: "1", Name: "event 2", }, &models.Event{ Id: "6", OwnerId: "1", Name: "event 3", }, &models.Event{ Id: "7", OwnerId: "1", Name: "generic event", }, &models.Event{ Id: "8", OwnerId: "1", Name: "generic event", }, // Not owned by User 1. &models.Event{ Id: "9", OwnerId: "2", Name: "not owned", }, }, }) s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { records.QueryGET(user.NewContext(context.Background(), &models.User{Id: "1"}), w, r, db, services.NewTestLogger(t)) })) p := s.URL + "?" + url.Values{ "query/Kind": []string{"event"}, }.Encode() resp, err := http.Get(p) if err != nil { t.Fatalf("http.Get error: %v", err) } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) body := string(b) if err != nil { t.Fatalf("ioutil.ReadAll error: %v", err) } t.Logf("resp.Body:\n%s", body) contents := map[string]bool{ "Query": true, "5 results.": true, "event 1": true, "event 2": true, "event 3": true, "generic event": true, "Edit": true, "/records/edit/?kind=event&id=8": true, "/records/edit/?kind=event&id=9": false, "not owned": false, } for content, want := range contents { if got := strings.Contains(body, content); got != want { t.Errorf("bytes.Contains(body, %q): got %t, want %t", content, got, want) } } }
func TestEditPOST(t *testing.T) { db := mem.NewDB() u, _, err := user.Create(db, "username", "password") if err != nil { t.Fatalf("user.Create error: %v", err) } e := &models.Event{ Id: db.NewID().String(), OwnerId: u.Id, Name: "old name", Data: map[string]interface{}{ "sensor": 4, }, Time: time.Now(), } if err := db.Save(e); err != nil { t.Fatalf("db.Save error: %v", err) } s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if strings.Contains(r.RequestURI, "/records/edit/") { records.EditPOST(user.NewContext(context.Background(), u), w, r, db, services.NewTestLogger(t)) return } w.WriteHeader(http.StatusOK) w.Write([]byte(`default test handler`)) })) p := s.URL + "/records/edit/?" + url.Values{ "kind": []string{"event"}, "id": []string{e.Id}, "event/Name": []string{"new eman"}, "event/Data": []string{`{"sensor": 4, "sensor2": 9}`}, }.Encode() resp, err := http.Post(p, "", new(bytes.Buffer)) if err != nil { t.Fatalf("http.Post error: %v", err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatalf("iotuil.ReadAll error: %v", err) } t.Logf("resp.Body:\n%s", body) ue := &models.Event{Id: e.Id} if err := db.PopulateByID(ue); err != nil { t.Fatalf("db.PopulateByID error: %v", err) } if got, want := ue.Name, "new eman"; got != want { t.Errorf("ue.Name: got %q, want %q", got, want) } if got, want := ue.Data, map[string]interface{}{"sensor": 4.0, "sensor2": 9.0}; !reflect.DeepEqual(got, want) { t.Errorf("ue.Data: got %v, want %v", got, want) } if got, want := ue.Time, e.Time; got != want { t.Errorf("ue.Time: got %v, want %v", got, want) } if got, want := ue.OwnerId, e.OwnerId; got != want { t.Errorf("ue.OwnerId: got %q, want %q", got, want) } }
func TestCreatePOST(t *testing.T) { adb, dbc, ac, closers, err := records_test.ClientsFromState(data.State{ models.Kind_USER: []*data.Record{ *data.Record{ Kind: models.Kind_USER, User: &models.User{ Id: "1", }, }, }, models.Kind_CREDENTIAL: []*data.Record{ &data.Record{ Kind: models.Kind_CREDENTIAL, Credential: &models.Credential{ Id: "2", OwnerId: "1", Type: models.Credential_PASSWORD, Public: "username", Private: "password", }, }, }, }) defer func() { records_test.CloseAll(closers) }() wui := records.NewWebUI(adb, ac) s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { records.CreatePOST(user.NewContext(context.Background(), u), w, r, db, services.NewTestLogger(t), webuiclient) })) p := s.URL + "?" + url.Values{ "kind": []string{"EVENT"}, "EVENT/OwnerId": []string{"1"}, "EVENT/Name": []string{"event name"}, "EVENT/Quantities": []string{`[{"name": "sensor", "value": 45}]`}, }.Encode() resp, err := http.Post(p, "", new(bytes.Buffer)) if err != nil { t.Fatalf("http.Post error: %v", err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { t.Fatalf("ioutil.ReadAll error: %v", err) } t.Logf("resp.Body:\n%s", body) if err := data.CompareState(dbc, data.State{ models.Kind_USER: []*data.Record{ *data.Record{ Kind: models.Kind_USER, User: &models.User{ Id: "1", }, }, }, models.Kind_CREDENTIAL: []*data.Record{ &data.Record{ Kind: models.Kind_CREDENTIAL, Credential: &models.Credential{ Id: "2", OwnerId: "1", Type: models.Credential_PASSWORD, Public: "username", Private: "password", }, }, }, models.Kind_EVENT: []*data.Record{ &data.Record{ Kind: models.Kind_EVENT, Event: &models.Event{ Id: "3", OwnerId: "1", Name: "event name", Quantities: []*Quantity{ Name: "sensor", Value: 45, }, }, }, }, }); err != nil { t.Errorf("data.CompareState error: %v", err) } }