Переглянути джерело

Working Memory repository tests, 93% coverage.

Frederic G. MARAND 5 роки тому
батько
коміт
92058843f9
5 змінених файлів з 104 додано та 26 видалено
  1. 26 0
      domain/domain_api.go
  2. 6 11
      domain/domain_spi.go
  3. 6 4
      domain/short_url.go
  4. 19 11
      infrastructure/memory.go
  5. 47 0
      infrastructure/memory_test.go

+ 26 - 0
domain/domain_api.go

@@ -0,0 +1,26 @@
+package domain
+
+func GetTargetURL(shortURL string) (target string, err error) {
+	su := ShortURL{URL: URL(shortURL)}
+	tu, err := shortURLRepository.GetTarget(su)
+	if err != nil {
+		target = ""
+	} else {
+		target = string(tu.URL)
+	}
+
+	return
+}
+
+func GetShortURL(targetURL string) (short string, isNew bool, err error) {
+	tu := TargetURL{URL: URL(targetURL)}
+	su, isNew, err := targetURLRepository.GetShort(tu)
+	if err != nil {
+		short = ""
+		isNew = false
+	} else {
+		short = string(su.URL)
+	}
+
+	return
+}

+ 6 - 11
domain/domain.go → domain/domain_spi.go

@@ -3,22 +3,17 @@ package domain
 var shortURLRepository ShortURLRepository
 var targetURLRepository TargetURLRepository
 
-func GetTargetURL(shortURL string) (string, error) {
-	return "", nil
-}
-
-func GetShortURL(targetURL string) (string, error) {
-	return "", nil
-}
-
 type ShortURLRepository interface {
 	GetTarget(su ShortURL) (TargetURL, error)
-	GetByTarget(tu TargetURL) (ShortURL, error)
 }
 
 type TargetURLRepository interface {
-	GetShort(tu TargetURL) (ShortURL, error)
-	GetByShort(su ShortURL) (TargetURL, error)
+	/*
+	GetShort returns the ShortURL for a given TargetURL.
+
+	In the results, isNew will be true if the ShortURL was created for this occasion.
+	 */
+	GetShort(tu TargetURL) (su ShortURL, isNew bool, err error)
 }
 
 func RegisterRepositories(sur ShortURLRepository, tur TargetURLRepository) {

+ 6 - 4
domain/short_url.go

@@ -18,13 +18,15 @@ func (su ShortURL) Target() TargetURL {
 /*
 MakeShortURL creates a ShortURL instance from a given RedirectURL/target pair.
 */
-func NewUnspecifiedShortURL(target TargetURL) (*ShortURL, error) {
+func NewUnspecifiedShortURL(target TargetURL) (ShortURL, error) {
+	var su ShortURL
 	if target.IsEmpty() {
-		return nil, errors.New("cannot target empty RedirectURL")
+		return su, errors.New("cannot target empty RedirectURL")
 	}
 
 	// FIXME: will cause collisions.
 	url := URL(strconv.Itoa(rand.Intn(1 << 31)))
-	u := ShortURL{url, target}
-	return &u, nil
+	su = ShortURL{url, target}
+	return su, nil
 }
+

+ 19 - 11
infrastructure/memory.go

@@ -14,6 +14,10 @@ var shorts = make(urlmap)
 type MemoryShortURLRepository struct {
 }
 
+type MemoryTargetURLRepository struct {
+
+}
+
 func (r MemoryShortURLRepository) GetTarget(su domain.ShortURL) (domain.TargetURL, error) {
 	var tu domain.TargetURL
 	var err error
@@ -26,19 +30,23 @@ func (r MemoryShortURLRepository) GetTarget(su domain.ShortURL) (domain.TargetUR
 	return tu, err
 }
 
-func (r MemoryShortURLRepository) GetByTarget(tu domain.TargetURL) (domain.ShortURL, error) {
-	var su domain.ShortURL
-	var err error
-
+func (s MemoryTargetURLRepository) GetShort(tu domain.TargetURL) (su domain.ShortURL, isNew bool, err error) {
+	// If short exists, just return it.
 	if s, ok := shorts[tu.URL]; ok {
 		su = domain.ShortURL{URL: s}
-	} else {
-		err = errors.New("not found")
+		return su, false, err
 	}
-	return su, err
-}
 
-func (r MemoryShortURLRepository) add(s domain.ShortURL, t domain.TargetURL) {
-	targets[s.URL] = t.URL
-	shorts[t.URL] = s.URL
+	// If it doesn't exist, attempt to create it.
+	su, err = domain.NewUnspecifiedShortURL(tu)
+	if err != nil {
+		// Creation failed.
+		return su, false, err
+	}
+
+	shorts[tu.URL] = su.URL
+	targets[su.URL] = tu.URL
+
+	return su, true, err
 }
+

+ 47 - 0
infrastructure/memory_test.go

@@ -0,0 +1,47 @@
+package infrastructure
+
+import (
+	"code.osinet.fr/fgm/kurz/domain"
+	"testing"
+	)
+
+const example_valid_http_url = "https://example.com"
+
+func TestEmptyRepo(test *testing.T) {
+
+	domain.RegisterRepositories(
+		MemoryShortURLRepository{},
+		MemoryTargetURLRepository{},
+	)
+
+	_, err := domain.GetTargetURL("whatever")
+	if err == nil {
+		test.Error("Empty repository should not find a target for any URL")
+	}
+
+	s1, isNew, err := domain.GetShortURL(example_valid_http_url)
+	if err != nil {
+		test.Error("Creating a short URL for a valid URL should not fail")
+	}
+	if !isNew {
+		test.Error("The first short URL in an empty repository should be new")
+	}
+	s2, isNew, err := domain.GetShortURL(example_valid_http_url)
+	if err != nil {
+		test.Error("Creating a short URL for a valid URL should not fail")
+	}
+	if isNew {
+		test.Error("The second short URL for an already shortened URL should not be new")
+	}
+	if s1 != s2 {
+		test.Error("The second short URL for an already shortened URL should be the same as the first one")
+	}
+
+	t, err := domain.GetTargetURL(s1)
+	if err != nil {
+		test.Error("Repository should find a target for an existing short URL")
+	}
+	if t != example_valid_http_url {
+		test.Error("Target URL for a short URL should match the target it was created for")
+	}
+}