Пример #1
0
func TestUnlock(t *testing.T) {
	l1 := &testUnlocker{
		field1: nonce + payloadBase64Delimiter + string(cypherText),
		field2: nonce + payloadBase64Delimiter + string(cypherText),
	}
	l2 := &testUnlocker{
		field1: nonce + payloadBase64Delimiter + string(cypherText),
		field2: nonce + payloadBase64Delimiter + string(cypherText),
	}

	context := ctx.NewContext()
	store := NewStore(context)
	store.Save(l1, l2)

	err := store.Unlock()
	if err != nil {
		t.Errorf("Unexpected error: %s", err)
		return
	}
	if !l1.called || !l2.called {
		t.Errorf("Unlocker not called")
		return
	}
	expected := string(plainText)
	if !(l1.field1 == expected && l1.field2 == expected && l2.field1 == expected && l2.field2 == expected) {
		t.Errorf("Unexpected field values: %s", l1.field1)
	}
}
Пример #2
0
func TestHydrateEntitiesWithPreloaded(t *testing.T) {
	resetRegistry()
	context := ctx.NewContext()
	Preload(context, "users", map[string]interface{}{
		"u2": u2,
	})
	Preload(context, "products", map[string]interface{}{
		"p2": p2,
	})
	RegisterEntityHandler("users", func(_ *ctx.Context, ids []string) (map[string]interface{}, error) {
		return map[string]interface{}{
			"u1": u1,
		}, nil
	})
	RegisterEntityHandler("products", func(_ *ctx.Context, ids []string) (map[string]interface{}, error) {
		return map[string]interface{}{
			"p1": p1,
		}, nil
	})
	entities, err := hydrateEntitiesFromMap(context, map[string]map[string]bool{
		"users":    {"u1": true},
		"products": {"p1": true},
	})
	if err != nil {
		t.Errorf("Unexpected error: %s", err)
	}
	if !reflect.DeepEqual(entities, map[string]map[string]interface{}{
		"users":    {"u1": u1, "u2": u2},
		"products": {"p1": p1, "p2": p2},
	}) {
		t.Errorf("Unexpected map received: %s", entities)
	}
}
Пример #3
0
// No handler
func TestHydrateEntitiesFromMapNoHandler(t *testing.T) {
	resetRegistry()
	_, err := hydrateEntitiesFromMap(ctx.NewContext(), map[string]map[string]bool{
		"users": {"u1": true},
	})
	if err == nil {
		t.Errorf("Expected error, got none: %s", err)
	}
}
Пример #4
0
func TestHydrateEntitiesFromMapEmptyMap(t *testing.T) {
	resetRegistry()
	entities, err := hydrateEntitiesFromMap(ctx.NewContext(), map[string]map[string]bool{})
	if err != nil {
		t.Errorf("Expected no error: %s", err)
	}
	if !reflect.DeepEqual(entities, map[string]map[string]interface{}{}) {
		t.Errorf("Unexpected map received: %s", entities)
	}
}
Пример #5
0
func TestHydrateEntitiesFromMapMultipleFailures(t *testing.T) {
	resetRegistry()
	RegisterEntityHandler("users", func(_ *ctx.Context, ids []string) (map[string]interface{}, error) {
		return nil, fmt.Errorf("Failure")
	})
	RegisterEntityHandler("products", func(_ *ctx.Context, ids []string) (map[string]interface{}, error) {
		return nil, fmt.Errorf("Failure")
	})
	_, err := hydrateEntitiesFromMap(ctx.NewContext(), map[string]map[string]bool{
		"users":    {"u1": true, "u2": true},
		"products": {"p1": true, "p2": true},
	})
	if err == nil {
		t.Errorf("Expected an error")
	}
}
Пример #6
0
func TestMultiError(t *testing.T) {
	newNonce, _ := NewNonce()
	// Both of these unlockers will fail since they have the wrong nonce.
	l1 := &testUnlocker{
		field1: newNonce + payloadBase64Delimiter + string(cypherText),
		field2: newNonce + payloadBase64Delimiter + string(cypherText),
	}
	l2 := &testUnlocker{
		field1: newNonce + payloadBase64Delimiter + string(cypherText),
		field2: newNonce + payloadBase64Delimiter + string(cypherText),
	}

	context := ctx.NewContext()
	store := NewStore(context)
	store.Save(l1, l2)

	err := store.Unlock()
	if err == nil {
		t.Errorf("Unexpected lack of an error")
	}
}
Пример #7
0
func TestSingleError(t *testing.T) {
	newNonce, _ := NewNonce()
	// Supply one correct and one incorrect unlocker.
	l1 := &testUnlocker{
		field1: newNonce + payloadBase64Delimiter + string(cypherText),
		field2: newNonce + payloadBase64Delimiter + string(cypherText),
	}
	l2 := &testUnlocker{
		field1: nonce + payloadBase64Delimiter + string(cypherText),
		field2: nonce + payloadBase64Delimiter + string(cypherText),
	}

	context := ctx.NewContext()
	store := NewStore(context)
	store.Save(l1, l2)

	err := store.Unlock()
	if err == nil {
		t.Errorf("Unexpected lack of an error")
	}
}
Пример #8
0
// HTTPHandler takes an ActionHandler and returns a http.Handler instance
// that can be used. The type and action are used to determine the context in
// several areas, such as transformers and metrics.
func (p *ActionProcessor) HTTPHandler(typ, action string, handler ActionHandler) httprouter.Handle {
	// Create a new timer for timing this handler.
	timer := metrics.NewTimer()
	p.MetricsRegistry.Register(typ+"-"+action, timer)
	sideloadTimer := metrics.NewTimer()
	p.MetricsRegistry.Register(typ+"-"+action+"-sideload", sideloadTimer)
	unlockTimer := metrics.NewTimer()
	p.MetricsRegistry.Register(typ+"-"+action+"-unlock", unlockTimer)

	return httprouter.Handle(func(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
		// At the end of this function, add a time metric.
		defer timer.UpdateSince(time.Now())

		// Create a new context for this action.
		context := ctx.NewContext()
		context.Request = r
		context.EntityType = typ
		SetContextParams(context, params)

		// Get any criteria, and transform it if required.
		criteria := RequestCriteria(r)
		for _, transformer := range requestCriteriaTransformers {
			transformer(context, criteria)
		}
		// Make the criteria available on the content.
		SetContextCriteria(context, criteria)

		// Get the base payload back from the ActionHandler instance.
		payload, code, err := handler.HandleAction(context)
		if err != nil {
			RespondWithError(w, r, err)
			return
		}

		// If an empty response is required, return an empty response.
		if payload == EmptyResponse {
			RespondWithStatusCode(w, r, code)
			return
		}

		// Build up a response.
		response := Response{
			Payload: payload,
		}

		if p.SideloadEnabled {
			start := time.Now()
			// Retrieve any sideloaded entities.
			sideloaded, err := sideload.Load(context, payload, criteria.Sideload)

			response.Sideload = &sideloaded
			if err != nil {
				timer.UpdateSince(start)
				RespondWithError(w, r, err)
				return
			}
			timer.UpdateSince(start)
		}

		// Unlock any entities registered for this request.
		unlockStartTime := time.Now()
		err = lynx.ContextStore(context).Unlock()
		unlockTimer.UpdateSince(unlockStartTime)

		if err != nil {
			RespondWithError(w, r, err)
			return
		}

		RespondWithData(w, r, response, code)
	})
}