summary refs log blame commit diff stats
path: root/query.go
blob: 63e203c1fbff5301f67feea842174ac5b365c9fb (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14


            
             









                                                
                                                                                


         












                                                       
         

                   

 












                                               



                                                             
                                                                     


                                  











                                                                
                                
                                                              

                                           
                               
                                                             



                                           




                                                                         


                                   
                                              


                                                          











                                                            
                
                                                                   

         
                                  


                                               
 
                  
 
package main

import (
	"fmt"
	"log"
	"net/http"
	"strings"

	"github.com/gorilla/mux"
)

func apiErrCheck(err error, r *http.Request) {
	if err != nil {
		uip := getIPFromCtx(r.Context())
		log.Printf("*** %v :: %v %v :: %v\n", uip, r.Method, r.URL, err)
	}
}

// Takes the output of queries and formats it for
// an HTTP response. Iterates over the string slice,
// appending each entry to a byte slice, and adding
// newlines where appropriate.
func parseQueryOut(out []string) []byte {
	var data []byte

	for _, e := range out {
		data = append(data, []byte(e)...)

		if !strings.HasSuffix(e, "\n") {
			data = append(data, byte('\n'))
		}
	}

	return data
}

// Removes duplicate statuses from query output
func uniq(str []string) []string {
	keys := make(map[string]bool)
	out := []string{}
	for _, e := range str {
		if _, ok := keys[e]; !ok {
			keys[e] = true
			out = append(out, e)
		}
	}
	return out
}

// apiUserQuery is called via apiEndpointHandler when
// the endpoint is "users" and r.FormValue("q") is not empty.
// It queries the registry cache for users or user URLs
// matching the term supplied via r.FormValue("q")
func apiEndpointQuery(w http.ResponseWriter, r *http.Request) error {
	query := r.FormValue("q")
	urls := r.FormValue("url")
	var out []string
	var err error

	vars := mux.Vars(r)
	endpoint := vars["endpoint"]

	// Handle user URL queries first, then nickname queries.
	// Concatenate both outputs if they're both set.
	// Also handle mention queries and status queries.
	// If we made it this far and 'default' is matched,
	// something went very wrong.
	switch endpoint {
	case "users":
		if query != "" {
			out, err = twtxtCache.QueryUser(query)
			apiErrCheck(err, r)
		}
		if urls != "" {
			out, err = twtxtCache.QueryUser(urls)
			apiErrCheck(err, r)
		}

	case "mentions":
		if urls == "" {
			return fmt.Errorf("missing URL in mention query")
		}
		urls += ">"
		out, err = twtxtCache.QueryInStatus(urls)
		apiErrCheck(err, r)

	case "tweets":
		query = strings.ToLower(query)
		out, err = twtxtCache.QueryInStatus(query)
		apiErrCheck(err, r)

		query = strings.Title(query)
		out2, err := twtxtCache.QueryInStatus(query)
		apiErrCheck(err, r)

		query = strings.ToUpper(query)
		out3, err := twtxtCache.QueryInStatus(query)
		apiErrCheck(err, r)

		out = append(out, out2...)
		out = append(out, out3...)
		out = uniq(out)

	default:
		return fmt.Errorf("endpoint query, no cases match")
	}

	data := parseQueryOut(out)

	w.Header().Set("Content-Type", txtutf8)
	_, err = w.Write(data)

	return err
}
f">get_field_type_returns_correct_type(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); g_hash_table_insert(form->tag_to_var, strdup("tag2"), strdup("var2")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_TEXT_SINGLE; field1->values = g_slist_append(field1->values, strdup("value1")); form->fields = g_slist_append(form->fields, field1); FormField *field2 = _new_field(); field2->var = strdup("var2"); field2->type_t = FIELD_TEXT_MULTI; field2->values = g_slist_append(field2->values, strdup("value2")); form->fields = g_slist_append(form->fields, field2); form_field_type_t result = form_get_field_type(form, "tag2"); assert_int_equal(result, FIELD_TEXT_MULTI); form_destroy(form); } void set_value_adds_when_none(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); g_hash_table_insert(form->tag_to_var, strdup("tag2"), strdup("var2")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_TEXT_SINGLE; field1->values = g_slist_append(field1->values, strdup("value1")); form->fields = g_slist_append(form->fields, field1); FormField *field2 = _new_field(); field2->var = strdup("var2"); field2->type_t = FIELD_LIST_SINGLE; form->fields = g_slist_append(form->fields, field2); form_set_value(form, "tag2", "a new value"); int length = 0; char *value = NULL; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var2") == 0) { length = g_slist_length(field->values); value = field->values->data; break; } curr_field = g_slist_next(curr_field); } assert_int_equal(length, 1); assert_string_equal(value, "a new value"); form_destroy(form); } void set_value_updates_when_one(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); g_hash_table_insert(form->tag_to_var, strdup("tag2"), strdup("var2")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_TEXT_SINGLE; form->fields = g_slist_append(form->fields, field1); FormField *field2 = _new_field(); field2->var = strdup("var2"); field2->type_t = FIELD_LIST_SINGLE; field2->values = g_slist_append(field2->values, strdup("value2")); form->fields = g_slist_append(form->fields, field2); form_set_value(form, "tag2", "a new value"); int length = 0; char *value = NULL; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var2") == 0) { length = g_slist_length(field->values); value = field->values->data; break; } curr_field = g_slist_next(curr_field); } assert_int_equal(length, 1); assert_string_equal(value, "a new value"); form_destroy(form); } void add_unique_value_adds_when_none(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); g_hash_table_insert(form->tag_to_var, strdup("tag2"), strdup("var2")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_JID_MULTI; form->fields = g_slist_append(form->fields, field1); FormField *field2 = _new_field(); field2->var = strdup("var2"); field2->type_t = FIELD_LIST_SINGLE; field2->values = g_slist_append(field2->values, strdup("value2")); form->fields = g_slist_append(form->fields, field2); gboolean ret = form_add_unique_value(form, "tag1", "me@server.com"); int length = 0; char *value = NULL; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); value = field->values->data; break; } curr_field = g_slist_next(curr_field); } assert_true(ret); assert_int_equal(length, 1); assert_string_equal(value, "me@server.com"); form_destroy(form); } void add_unique_value_does_nothing_when_exists(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); g_hash_table_insert(form->tag_to_var, strdup("tag2"), strdup("var2")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_JID_MULTI; field1->values = g_slist_append(field1->values, strdup("me@server.com")); form->fields = g_slist_append(form->fields, field1); FormField *field2 = _new_field(); field2->var = strdup("var2"); field2->type_t = FIELD_LIST_SINGLE; field2->values = g_slist_append(field2->values, strdup("value2")); form->fields = g_slist_append(form->fields, field2); gboolean ret = form_add_unique_value(form, "tag1", "me@server.com"); int length = 0; char *value = NULL; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); value = field->values->data; break; } curr_field = g_slist_next(curr_field); } assert_false(ret); assert_int_equal(length, 1); assert_string_equal(value, "me@server.com"); form_destroy(form); } void add_unique_value_adds_when_doesnt_exist(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); g_hash_table_insert(form->tag_to_var, strdup("tag2"), strdup("var2")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_JID_MULTI; field1->values = g_slist_append(field1->values, strdup("dolan@server.com")); field1->values = g_slist_append(field1->values, strdup("kieran@server.com")); field1->values = g_slist_append(field1->values, strdup("chi@server.com")); form->fields = g_slist_append(form->fields, field1); FormField *field2 = _new_field(); field2->var = strdup("var2"); field2->type_t = FIELD_LIST_SINGLE; field2->values = g_slist_append(field2->values, strdup("value2")); form->fields = g_slist_append(form->fields, field2); gboolean ret = form_add_unique_value(form, "tag1", "me@server.com"); int length = 0; int count = 0; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); GSList *curr_value = field->values; while (curr_value != NULL) { if (g_strcmp0(curr_value->data, "me@server.com") == 0) { count++; } curr_value = g_slist_next(curr_value); } break; } curr_field = g_slist_next(curr_field); } assert_true(ret); assert_int_equal(length, 4); assert_int_equal(count, 1); form_destroy(form); } void add_value_adds_when_none(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; form->fields = g_slist_append(form->fields, field1); form_add_value(form, "tag1", "somevalue"); int length = 0; char *value = NULL; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); value = field->values->data; break; } curr_field = g_slist_next(curr_field); } assert_int_equal(length, 1); assert_string_equal(value, "somevalue"); form_destroy(form); } void add_value_adds_when_some(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; field1->values = g_slist_append(field1->values, strdup("some text")); field1->values = g_slist_append(field1->values, strdup("some more text")); field1->values = g_slist_append(field1->values, strdup("yet some more text")); form->fields = g_slist_append(form->fields, field1); form_add_value(form, "tag1", "new value"); int num_values = 0; int new_value_count = 0; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { GSList *curr_value = field->values; while (curr_value != NULL) { num_values++; if (g_strcmp0(curr_value->data, "new value") == 0) { new_value_count++; } curr_value = g_slist_next(curr_value); } break; } curr_field = g_slist_next(curr_field); } assert_int_equal(num_values, 4); assert_int_equal(new_value_count, 1); form_destroy(form); } void add_value_adds_when_exists(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; field1->values = g_slist_append(field1->values, strdup("some text")); field1->values = g_slist_append(field1->values, strdup("some more text")); field1->values = g_slist_append(field1->values, strdup("yet some more text")); field1->values = g_slist_append(field1->values, strdup("new value")); form->fields = g_slist_append(form->fields, field1); form_add_value(form, "tag1", "new value"); int num_values = 0; int new_value_count = 0; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { GSList *curr_value = field->values; while (curr_value != NULL) { num_values++; if (g_strcmp0(curr_value->data, "new value") == 0) { new_value_count++; } curr_value = g_slist_next(curr_value); } break; } curr_field = g_slist_next(curr_field); } assert_int_equal(num_values, 5); assert_int_equal(new_value_count, 2); form_destroy(form); } void remove_value_does_nothing_when_none(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; form->fields = g_slist_append(form->fields, field1); gboolean res = form_remove_value(form, "tag1", "some value"); int length = -1; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); } curr_field = g_slist_next(curr_field); } assert_false(res); assert_int_equal(length, 0); form_destroy(form); } void remove_value_does_nothing_when_doesnt_exist(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; field1->values = g_slist_append(field1->values, strdup("value1")); field1->values = g_slist_append(field1->values, strdup("value2")); field1->values = g_slist_append(field1->values, strdup("value3")); field1->values = g_slist_append(field1->values, strdup("value4")); form->fields = g_slist_append(form->fields, field1); gboolean res = form_remove_value(form, "tag1", "value5"); int length = -1; int value_count = 0; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); GSList *curr_value = field->values; while (curr_value != NULL) { if (g_strcmp0(curr_value->data, "value5") == 0) { value_count++; } curr_value = g_slist_next(curr_value); } } curr_field = g_slist_next(curr_field); } assert_false(res); assert_int_equal(length, 4); assert_int_equal(value_count, 0); form_destroy(form); } void remove_value_removes_when_one(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; field1->values = g_slist_append(field1->values, strdup("value4")); form->fields = g_slist_append(form->fields, field1); gboolean res = form_remove_value(form, "tag1", "value4"); int length = -1; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); } curr_field = g_slist_next(curr_field); } assert_true(res); assert_int_equal(length, 0); form_destroy(form); } void remove_value_removes_when_many(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; field1->values = g_slist_append(field1->values, strdup("value1")); field1->values = g_slist_append(field1->values, strdup("value2")); field1->values = g_slist_append(field1->values, strdup("value3")); field1->values = g_slist_append(field1->values, strdup("value4")); form->fields = g_slist_append(form->fields, field1); gboolean res = form_remove_value(form, "tag1", "value2"); int length = -1; int value_count = 0; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); GSList *curr_value = field->values; while (curr_value != NULL) { if (g_strcmp0(curr_value->data, "value2") == 0) { value_count++; } curr_value = g_slist_next(curr_value); } } curr_field = g_slist_next(curr_field); } assert_true(res); assert_int_equal(length, 3); assert_int_equal(value_count, 0); form_destroy(form); } void remove_text_multi_value_does_nothing_when_none(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; form->fields = g_slist_append(form->fields, field1); gboolean res = form_remove_text_multi_value(form, "tag1", 3); int length = -1; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); } curr_field = g_slist_next(curr_field); } assert_false(res); assert_int_equal(length, 0); form_destroy(form); } void remove_text_multi_value_does_nothing_when_doesnt_exist(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; field1->values = g_slist_append(field1->values, strdup("value1")); field1->values = g_slist_append(field1->values, strdup("value2")); field1->values = g_slist_append(field1->values, strdup("value3")); field1->values = g_slist_append(field1->values, strdup("value4")); form->fields = g_slist_append(form->fields, field1); gboolean res = form_remove_text_multi_value(form, "tag1", 5); int length = -1; int value_count = 0; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); GSList *curr_value = field->values; while (curr_value != NULL) { if (g_strcmp0(curr_value->data, "value5") == 0) { value_count++; } curr_value = g_slist_next(curr_value); } } curr_field = g_slist_next(curr_field); } assert_false(res); assert_int_equal(length, 4); assert_int_equal(value_count, 0); form_destroy(form); } void remove_text_multi_value_removes_when_one(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; field1->values = g_slist_append(field1->values, strdup("value4")); form->fields = g_slist_append(form->fields, field1); gboolean res = form_remove_text_multi_value(form, "tag1", 1); int length = -1; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); } curr_field = g_slist_next(curr_field); } assert_true(res); assert_int_equal(length, 0); form_destroy(form); } void remove_text_multi_value_removes_when_many(void **state) { DataForm *form = _new_form(); g_hash_table_insert(form->tag_to_var, strdup("tag1"), strdup("var1")); FormField *field1 = _new_field(); field1->var = strdup("var1"); field1->type_t = FIELD_LIST_MULTI; field1->values = g_slist_append(field1->values, strdup("value1")); field1->values = g_slist_append(field1->values, strdup("value2")); field1->values = g_slist_append(field1->values, strdup("value3")); field1->values = g_slist_append(field1->values, strdup("value4")); form->fields = g_slist_append(form->fields, field1); gboolean res = form_remove_text_multi_value(form, "tag1", 2); int length = -1; int value_count = 0; GSList *curr_field = form->fields; while (curr_field != NULL) { FormField *field = curr_field->data; if (g_strcmp0(field->var, "var1") == 0) { length = g_slist_length(field->values); GSList *curr_value = field->values; while (curr_value != NULL) { if (g_strcmp0(curr_value->data, "value2") == 0) { value_count++; } curr_value = g_slist_next(curr_value); } } curr_field = g_slist_next(curr_field); } assert_true(res); assert_int_equal(length, 3); assert_int_equal(value_count, 0); form_destroy(form); }