Beispiel #1
0
Datei: main.go Projekt: elos/gaia
func main() {
	var (
		mongo = flag.String("mongo", "localhost", "Address of mongo instance")
	)

	db, err := models.MongoDB(*mongo)
	if err != nil {
		log.Fatal(err)
	}

	iter, err := db.Query(models.TaskKind).Execute()
	if err != nil {
		log.Fatal(err)
	}

	count := 0
	t := models.NewTask()
	for iter.Next(t) {
		if task.IsComplete(t) {
			t.CompletedAt = t.UpdatedAt

			if err := db.Save(t); err != nil {
				log.Fatal(err)
			}

			count++
		}
	}

	log.Print("Migrated %d tasks", count)

	if err := iter.Close(); err != nil {
		log.Fatal(err)
	}
}
Beispiel #2
0
func TestRecordQuery(t *testing.T) {
	db, _, s := testInstance(t, context.Background())
	defer s.Close()

	user, cred := testUser(t, db)

	taskName := "task to retreive"
	task := models.NewTask()
	task.SetID(db.NewID())
	task.CreatedAt = time.Now()
	task.OwnerId = user.Id
	task.Name = taskName
	task.UpdatedAt = time.Now()
	if err := db.Save(task); err != nil {
		t.Fatal(err)
	}

	params := url.Values{}
	params.Set("kind", models.TaskKind.String())
	params.Set("id", task.ID().String())
	url := s.URL + "/record/query/?" + params.Encode()
	t.Logf("Constructed URL: %s", url)

	requestBody, err := json.Marshal(data.AttrMap{
		"name": taskName,
	})

	if err != nil {
		t.Fatal(err)
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
	if err != nil {
		t.Fatal(err)
	}
	req.SetBasicAuth(cred.Public, cred.Private)

	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.StatusOK {
		t.Fatalf("Expected status code of %d", http.StatusOK)
	}

	if !strings.Contains(string(body), taskName) {
		t.Fatal("Response body should have contained the task name")
	}
}
Beispiel #3
0
func TestRecordDELETE(t *testing.T) {
	db, _, s := testInstance(t, context.Background())
	defer s.Close()

	user, cred := testUser(t, db)

	taskName := "task to modify"
	task := models.NewTask()
	task.SetID(db.NewID())
	task.CreatedAt = time.Now()
	task.OwnerId = user.Id
	task.Name = taskName
	task.UpdatedAt = time.Now()
	if err := db.Save(task); err != nil {
		t.Fatal(err)
	}

	params := url.Values{}
	params.Set("kind", models.TaskKind.String())
	params.Set("id", task.ID().String())
	url := s.URL + "/record/?" + params.Encode()
	t.Logf("Constructed URL: %s", url)

	req, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		t.Fatal(err)
	}
	req.SetBasicAuth(cred.Public, cred.Private)

	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)
	}

	if string(body) != "" {
		t.Fatalf("Response body should be empty, but got: '%s'", string(body))
	}

	if err := db.PopulateByID(task); err != data.ErrNotFound {
		t.Fatal("The task should not be able to be found")
	}
}
Beispiel #4
0
Datei: x.go Projekt: elos/elos
func (c *XCommand) runReview(args []string) int {
	db := c.DB
	switch args[1] {
	case "taskweek":
		iter, err := db.Query(models.TaskKind).Select(data.AttrMap{"owner_id": c.UserID}).Execute()
		if err != nil {
			log.Fatal(err)
			return failure
		}

		oneWeekAgo := time.Now().Add(-7 * 24 * time.Hour)

		completedInLastWeek := make([]*models.Task, 0)

		t := models.NewTask()
		for iter.Next(t) {
			if t.CompletedAt.Local().After(oneWeekAgo.Local()) {
				completedInLastWeek = append(completedInLastWeek, t)
				t = models.NewTask()
			}
		}

		if len(completedInLastWeek) == 0 {
			c.UI.Output("No tasks completed in last week")
			return success
		}

		sort.Sort(task.ByCompletedAt(completedInLastWeek))

		for _, t := range completedInLastWeek {
			c.UI.Output(fmt.Sprintf("\t* %s [%s]", t.Name, t.CompletedAt.Local().Format("Mon Jan 2")))
		}

	}
	return success
}
Beispiel #5
0
func TestDB(t *testing.T) {
	db, _, s := testInstance(t, context.Background())
	defer s.Close()

	user, cred := testUser(t, db)

	gdb := &gaia.DB{
		URL:      s.URL,
		Username: cred.Public,
		Password: cred.Private,
		Client:   http.DefaultClient,
	}

	t.Log("Creating a test task")

	taskName := "task name"
	task := models.NewTask()
	task.SetID(db.NewID())
	task.CreatedAt = time.Now()
	task.OwnerId = user.Id
	task.Name = taskName
	task.UpdatedAt = time.Now()
	if err := db.Save(task); err != nil {
		t.Fatal(err)
	}

	t.Log("Test task created")

	t.Log("Creating a task to retrieve using the gaia db")

	getTask := models.NewTask()
	getTask.SetID(task.ID()) // use task's id

	t.Logf("Retrieving task using ID: %s and the gaia db", task.ID().String())
	if err := gdb.PopulateByID(getTask); err != nil {
		t.Fatal(err)
	}
	t.Logf("Task retrieved: %+v", getTask)

	if getTask.Name != taskName {
		t.Fatal("Task names should match")
	}

	t.Log("Deleting task using the gaia db")
	if err := gdb.Delete(getTask); err != nil {
		t.Fatal(err)
	}
	t.Log("Task deleted")

	t.Log("Checking that task is no longer in real database")
	if err := db.PopulateByID(task); err != data.ErrNotFound {
		t.Fatal("Task should be gone")
	}
	t.Log("Checked")

	t.Log("Using gaia db to recreate that task")
	if err := gdb.Save(task); err != nil {
		t.Fatal(err)
	}
	t.Log("Recreated")

	t.Log("Checking that task back in real database")
	if err := db.PopulateByID(task); err != nil {
		t.Fatal("Task should be back")
	}

	if task.Name != taskName {
		t.Fatalf("Task name should be %s", taskName)
	}

	t.Log("Checked")

	t.Log("Changing task name")
	newName := "new name"
	getTask.Name = newName
	t.Log("Changed")

	t.Log("Using gaia db to update the task")
	if err := gdb.Save(getTask); err != nil {
		t.Fatal(err)
	}
	t.Log("Updated")

	t.Log("Re-retrieving that task from the real db")
	if err := db.PopulateByID(task); err != nil {
		t.Fatal(err)
	}
	t.Log("Retrieved")

	t.Log("Checking that the task was updated")
	if task.Name != newName {
		t.Fatalf("Save should have updated the task")
	}
	t.Log("Checked")

	t.Log("Querying for the task using gaia db")
	q := gdb.Query(models.TaskKind)
	q.Select(data.AttrMap{
		"name": newName,
	})
	iter, err := q.Execute()
	if err != nil {
		t.Fatal(err)
	}
	t.Log("Query executed")

	t.Log("Examining query results")

	result := models.NewTask()
	iter.Next(result)
	if iter.Next(result) != false {
		t.Fatal("Should only be one result")
	}

	if err := iter.Close(); err != nil {
		t.Fatal(err)
	}

	if result.ID().String() != task.ID().String() {
		t.Fatal("Ids should match")
	}

	if result.Name != newName {
		t.Fatal("should ahve retrievied the task with the new name")
	}

	t.Log("Examined")

	changes := db.Changes()

	eventName := "hello"
	e := models.NewEvent()
	e.SetID(db.NewID())
	e.SetOwner(user)
	e.Name = eventName
	if err := db.Save(e); err != nil {
		t.Fatal(err)
	}

	select {
	case c := <-*changes:
		t.Logf("Change received:\n%++v", c)
		if c.Record.(*models.Event).Name != eventName {
			t.Fatalf("Change should have been recieved with event record and name '%s'", eventName)
		}
	case <-time.After(50 * time.Millisecond):
		t.Fatalf("Timed out waiting for change")
	}
}
Beispiel #6
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)
}
Beispiel #7
0
func TestRecordChanges(t *testing.T) {
	ctx, cancelAllConnections := context.WithCancel(context.Background())
	defer cancelAllConnections()

	db, _, s := testInstance(t, ctx)
	defer s.Close()

	user, 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)
	params.Set("kind", models.TaskKind.String())
	wsURL += routes.RecordChanges + "?" + 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")

	time.Sleep(500 * time.Millisecond)

	t.Log("Creating task")
	taskName := "task to retreive"
	task := models.NewTask()
	task.SetID(db.NewID())
	task.CreatedAt = time.Now()
	task.OwnerId = user.Id
	task.Name = taskName
	task.UpdatedAt = time.Now()
	if err := db.Save(task); err != nil {
		t.Fatal(err)
	}
	t.Log("Task created")

	var ct transfer.ChangeTransport
	if err := websocket.JSON.Receive(ws, &ct); err != nil {
		t.Fatal(err)
	}

	tc := transfer.ChangeFrom(&ct, models.ModelFor(ct.RecordKind))

	t.Logf("Task Change Recieved: %++v", tc)

	t.Log("Cancelling the connection")
	cancelAllConnections()
	t.Log("\tcancelled")

	if tc.ChangeKind != data.Update {
		t.Fatal("Expected ChangeKind to be Update")
	}

	if tc.Record.(*models.Task).Name != taskName {
		t.Fatalf("Expected task name to be: '%s'", taskName)
	}
}
Beispiel #8
0
func TestRecordQuerySkip(t *testing.T) {
	db, _, s := testInstance(t, context.Background())
	defer s.Close()

	user, cred := testUser(t, db)

	task1 := models.NewTask()
	task1.SetID(db.NewID())
	task1.CreatedAt = time.Now()
	task1.OwnerId = user.Id
	task1.Name = "task1"
	task1.UpdatedAt = time.Now()
	if err := db.Save(task1); err != nil {
		t.Fatal(err)
	}

	task2 := models.NewTask()
	task2.SetID(db.NewID())
	task2.CreatedAt = time.Now()
	task2.OwnerId = user.Id
	task2.Name = "task2"
	task2.UpdatedAt = time.Now()
	if err := db.Save(task2); err != nil {
		t.Fatal(err)
	}

	params := url.Values{}
	params.Set("kind", models.TaskKind.String())
	params.Set("skip", "1")
	url := s.URL + "/record/query/?" + params.Encode()
	t.Logf("Constructed URL: %s", url)

	req, err := http.NewRequest("POST", url, nil)
	if err != nil {
		t.Fatal(err)
	}
	req.SetBasicAuth(cred.Public, cred.Private)

	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.StatusOK {
		t.Fatalf("Expected status code of %d", http.StatusOK)
	}

	// Should contain one or the other, but not both
	if strings.Contains(string(body), "task1") {
		if strings.Contains(string(body), "task2") {
			t.Fatal("Response body should have contained task2")
		}
	} else {
		if !strings.Contains(string(body), "task2") {
			t.Fatal("Response body should have contained task2")
		}
	}
}