Ejemplo n.º 1
0
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)
	}
}
Ejemplo n.º 2
0
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)
		}
	}
}
Ejemplo n.º 3
0
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)
	}
}
Ejemplo n.º 4
0
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)
	}
}
Ejemplo n.º 5
0
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)
	}
}
Ejemplo n.º 6
0
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)
		}
	}
}
Ejemplo n.º 7
0
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)
	}
}
Ejemplo n.º 8
0
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)
	}
}
Ejemplo n.º 9
0
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
}
Ejemplo n.º 10
0
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)
	}
}
Ejemplo n.º 11
0
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)
	}
}
Ejemplo n.º 12
0
// 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)
	}
}
Ejemplo n.º 13
0
// --- 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)
	}
}
Ejemplo n.º 14
0
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")
	}
}
Ejemplo n.º 15
0
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)
}
Ejemplo n.º 16
0
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)
		}
	}
}
Ejemplo n.º 17
0
// --- '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")
	}
}
Ejemplo n.º 18
0
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")
}
Ejemplo n.º 19
0
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)
		}
	}
}
Ejemplo n.º 20
0
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)
		}
	}
}
Ejemplo n.º 21
0
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)
	}
}
Ejemplo n.º 22
0
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)
	}
}