func TestWithInitStoreByToken(t *testing.T) { var newReq = func(i int) *http.Request { req, err := http.NewRequest(httputils.MethodGet, fmt.Sprintf("https://corestore.io/store/list/%d", i), nil) if err != nil { t.Fatal(err) } return req } tests := []struct { ctx context.Context wantStoreCode string wantErr error }{ {store.NewContextReader(context.Background(), nil), "de", store.ErrContextServiceNotFound}, {store.NewContextReader(context.Background(), getInitializedStoreService(scope.Option{Store: scope.MockCode("de")})), "de", ctxjwt.ErrContextJWTNotFound}, {newStoreServiceWithTokenCtx(scope.Option{Store: scope.MockCode("de")}, "de"), "de", nil}, {newStoreServiceWithTokenCtx(scope.Option{Store: scope.MockCode("at")}, "ch"), "at", store.ErrStoreNotActive}, {newStoreServiceWithTokenCtx(scope.Option{Store: scope.MockCode("de")}, "at"), "at", nil}, {newStoreServiceWithTokenCtx(scope.Option{Store: scope.MockCode("de")}, "a$t"), "de", store.ErrStoreCodeInvalid}, {newStoreServiceWithTokenCtx(scope.Option{Store: scope.MockCode("at")}, ""), "at", store.ErrStoreCodeInvalid}, {newStoreServiceWithTokenCtx(scope.Option{Group: scope.MockID(1)}, "de"), "de", nil}, {newStoreServiceWithTokenCtx(scope.Option{Group: scope.MockID(1)}, "ch"), "at", store.ErrStoreNotActive}, {newStoreServiceWithTokenCtx(scope.Option{Group: scope.MockID(1)}, " ch"), "at", store.ErrStoreCodeInvalid}, {newStoreServiceWithTokenCtx(scope.Option{Group: scope.MockID(1)}, "uk"), "at", store.ErrStoreChangeNotAllowed}, {newStoreServiceWithTokenCtx(scope.Option{Website: scope.MockID(2)}, "uk"), "au", store.ErrStoreChangeNotAllowed}, {newStoreServiceWithTokenCtx(scope.Option{Website: scope.MockID(2)}, "nz"), "nz", nil}, {newStoreServiceWithTokenCtx(scope.Option{Website: scope.MockID(2)}, "n z"), "au", store.ErrStoreCodeInvalid}, {newStoreServiceWithTokenCtx(scope.Option{Website: scope.MockID(2)}, "au"), "au", nil}, {newStoreServiceWithTokenCtx(scope.Option{Website: scope.MockID(2)}, ""), "au", store.ErrStoreCodeInvalid}, } for i, test := range tests { mw := store.WithInitStoreByToken()(finalInitStoreHandler(t, test.wantStoreCode)) rec := httptest.NewRecorder() surfErr := mw.ServeHTTPContext(test.ctx, rec, newReq(i)) if test.wantErr != nil { assert.EqualError(t, surfErr, test.wantErr.Error(), "Index %d", i) continue } assert.NoError(t, surfErr, "Index %d", i) } }
func TestWithInitStoreByToken_EqualPointers(t *testing.T) { // this Test is related to Benchmark_WithInitStoreByToken // The returned pointers from store.FromContextReader must be the // same for each request with the same request pattern. ctx := newStoreServiceWithTokenCtx(scope.Option{Website: scope.MockID(2)}, "nz") rec := httptest.NewRecorder() req, err := http.NewRequest(httputils.MethodGet, "https://corestore.io/store/list", nil) if err != nil { t.Fatal(err) } var equalStorePointer *store.Store mw := store.WithInitStoreByToken()(ctxhttp.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { _, haveReqStore, err := store.FromContextReader(ctx) if err != nil { return err } if equalStorePointer == nil { equalStorePointer = haveReqStore } if "nz" != haveReqStore.StoreCode() { t.Errorf("Have: %s\nWant: nz", haveReqStore.StoreCode()) } wantP := reflect.ValueOf(equalStorePointer) haveP := reflect.ValueOf(haveReqStore) if wantP.Pointer() != haveP.Pointer() { t.Errorf("Expecting equal pointers for each request.\nWant: %p\nHave: %p", equalStorePointer, haveReqStore) } return nil })) for i := 0; i < 10; i++ { if err := mw.ServeHTTPContext(ctx, rec, req); err != nil { t.Error(err) } } }
// Benchmark_WithInitStoreByToken-4 100000 17297 ns/op 9112 B/op 203 allocs/op => old bug // Benchmark_WithInitStoreByToken-4 2000000 810 ns/op 128 B/op 5 allocs/op => new func Benchmark_WithInitStoreByToken(b *testing.B) { // see TestWithInitStoreByToken_Alloc_Investigations_TEMP b.ReportAllocs() wantStoreCode := "nz" ctx := newStoreServiceWithTokenCtx(scope.Option{Website: scope.MockID(2)}, wantStoreCode) mw := store.WithInitStoreByToken()(benchValidationHandler(b, wantStoreCode)) rec := httptest.NewRecorder() req, err := http.NewRequest(httputils.MethodGet, "https://corestore.io/store/list/", nil) if err != nil { b.Fatal(err) } b.ResetTimer() for i := 0; i < b.N; i++ { if err := mw.ServeHTTPContext(ctx, rec, req); err != nil { b.Error(err) } } }
func ExampleWithInitStoreByToken() { initStore() ctx := store.NewContextReader(context.Background(), testStoreService) jwtService, err := ctxjwt.NewService(ctxjwt.WithPassword([]byte(`GÒph3r`))) finalHandler := ctxhttp.Chain( ctxhttp.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { _, haveReqStore, err := store.FromContextReader(ctx) if err != nil { return err } // now we know that the current request depends on the store view DE. fmt.Fprintf(w, "StoreCode: %s\n", haveReqStore.StoreCode()) return nil }), // executed 3rd store.WithInitStoreByToken(), // executed 2nd jwtService.WithParseAndValidate(), // executed 1st ) ts := httptest.NewServer(ctxhttp.NewAdapter(ctx, finalHandler)) defer ts.Close() // Setup GET request token, _, err := jwtService.GenerateToken( map[string]interface{}{ // Despite default store for Website ID 1 is AT we are currently // in the store context of DE. store.ParamName: "de", }, ) if err != nil { log.Fatal("jwtService.GenerateToken", "err", err) } req, err := http.NewRequest("GET", ts.URL, nil) if err != nil { log.Fatal("http.Get", "err", err) } ctxjwt.SetHeaderAuthorization(req, token) res, err := http.DefaultClient.Do(req) if err != nil { log.Fatal("http.DefaultClient.Do", "err", err) } response, err := ioutil.ReadAll(res.Body) if errC := res.Body.Close(); errC != nil { log.Fatal("res.Body.Close", "err", errC) } if err != nil { log.Fatal("ioutil.ReadAll", "err", err) } fmt.Printf("Response: %s\n", response) fmt.Printf("Log: %s\n", testDebugLogBuf.String()) // Output: // Response: StoreCode: de // // Log: }