github.com/uvalib/orcid-access-ws@v0.0.0-20250612130209-7d062dbabf9d/orcidaccessws/tests/service_test.go (about)

     1  package test
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/dgrijalva/jwt-go"
     6  	"github.com/uvalib/orcid-access-ws/orcidaccessws/api"
     7  	"gopkg.in/yaml.v2"
     8  	"io/ioutil"
     9  	"log"
    10  	"math/rand"
    11  	"strconv"
    12  	"strings"
    13  	"testing"
    14  	"time"
    15  )
    16  
    17  type config struct {
    18  	Endpoint string
    19  	Secret   string
    20  }
    21  
    22  var cfg = loadConfig()
    23  
    24  var goodCid = "dpg3k"
    25  var badCid = "badness"
    26  var goodOrcid = "0000-0003-4520-4923"
    27  var badOrcid = "9999-9999-0000-0000"
    28  var goodSearch = "Ellen Ramsey"
    29  var notFoundSearch = "hurunglyzit"
    30  var empty = " "
    31  var goodSearchStart = "0"
    32  var badSearchStart = "x"
    33  var goodSearchMax = "25"
    34  var badSearchMax = "x"
    35  
    36  var lcAlphaChars = "abcdefghijklmnopqrstuvwxyz"
    37  var numericChars = "0123456789"
    38  var numericAndLcAlphaChars = numericChars + lcAlphaChars
    39  
    40  //
    41  // test helpers
    42  //
    43  
    44  func randomOrcidAttributes() api.OrcidAttributes {
    45  
    46  	// see the RNG
    47  	rand.Seed(time.Now().UnixNano())
    48  
    49  	// list of possible characters for the ORCID
    50  	possible := []rune(numericChars)
    51  	orcid := fmt.Sprintf("%s-%s-%s-%s", randomString(possible, 4), randomString(possible, 4),
    52  		randomString(possible, 4), randomString(possible, 4))
    53  
    54  	// list of possible characters for the access tokens
    55  	possible = []rune(numericAndLcAlphaChars)
    56  	oauthAccess := randomString(possible, 32)
    57  	oauthRenew := randomString(possible, 32)
    58  	oauthScope := "/my/scope"
    59  	return api.OrcidAttributes{Orcid: orcid,
    60  		OauthAccessToken: oauthAccess, OauthRefreshToken: oauthRenew, OauthScope: oauthScope}
    61  }
    62  
    63  func randomCid() string {
    64  
    65  	// see the RNG
    66  	rand.Seed(time.Now().UnixNano())
    67  
    68  	// list of possible characters
    69  	possible := []rune(numericAndLcAlphaChars)
    70  
    71  	return randomString(possible, 5)
    72  }
    73  
    74  func randomUpdateCode() string {
    75  
    76  	// see the RNG
    77  	rand.Seed(time.Now().UnixNano())
    78  
    79  	// list of possible characters
    80  	possible := []rune(numericChars)
    81  
    82  	return randomString(possible, 6)
    83  }
    84  
    85  func workActivity() api.ActivityUpdate {
    86  
    87  	// see the RNG
    88  	rand.Seed(time.Now().UnixNano())
    89  
    90  	possible := []rune(lcAlphaChars)
    91  	title := fmt.Sprintf("Title-%s", randomString(possible, 32))
    92  	abstract := fmt.Sprintf("Abstract-%s", randomString(possible, 32))
    93  	pubDate := "2017-03-05"
    94  	url := fmt.Sprintf("www.foobar.com/%s", randomString(possible, 16))
    95  	persons := makePeople(2)
    96  	rt := "journal-article"
    97  
    98  	work := api.WorkSchema{Title: title, Abstract: abstract, PublicationDate: pubDate, URL: url, Authors: persons, ResourceType: rt}
    99  	return api.ActivityUpdate{Work: work}
   100  }
   101  
   102  func makePeople(number int) []api.Person {
   103  
   104  	people := make([]api.Person, number, number)
   105  	for ix := 0; ix < number; ix++ {
   106  
   107  		p := api.Person{
   108  			Index:     ix,
   109  			FirstName: fmt.Sprintf("first-%d", ix+1),
   110  			LastName:  fmt.Sprintf("last-%d", ix+1),
   111  		}
   112  		people[ix] = p
   113  	}
   114  	return people
   115  }
   116  
   117  func randomString(possible []rune, sz int) string {
   118  
   119  	b := make([]rune, sz)
   120  	for i := range b {
   121  		b[i] = possible[rand.Intn(len(possible))]
   122  	}
   123  	return string(b)
   124  }
   125  
   126  func ensureIdenticalOrcidsAttributes(t *testing.T, attributes1 *api.OrcidAttributes, attributes2 *api.OrcidAttributes) {
   127  
   128  	//log.Printf("%t", attributes1)
   129  	//log.Printf("%t", attributes2)
   130  
   131  	if attributes1.Orcid != attributes2.Orcid ||
   132  		attributes1.OauthAccessToken != attributes2.OauthAccessToken ||
   133  		attributes1.OauthRefreshToken != attributes2.OauthRefreshToken ||
   134  		attributes1.OauthScope != attributes2.OauthScope {
   135  		t.Fatalf("Expected identical attributes but they are not\n")
   136  	}
   137  }
   138  
   139  func ensureValidOrcidsAttributes(t *testing.T, orcids []*api.OrcidAttributes) {
   140  	for _, e := range orcids {
   141  		if emptyField(e.ID) ||
   142  			emptyField(e.Cid) ||
   143  			emptyField(e.Orcid) ||
   144  			emptyField(e.URI) ||
   145  			emptyField(e.CreatedAt) {
   146  			log.Printf("%v", e)
   147  			t.Fatalf("Expected non-empty field but one is empty\n")
   148  		}
   149  	}
   150  }
   151  
   152  func ensureValidSearchResults(t *testing.T, orcids []*api.OrcidDetails, expectedMax string, totalFound int) {
   153  	for _, e := range orcids {
   154  		ensureValidOrcidDetails(t, e)
   155  	}
   156  
   157  	max, _ := strconv.Atoi(expectedMax)
   158  	actualCount := len(orcids)
   159  	if actualCount > max {
   160  		t.Fatalf("Expected %v results, got %v\n", max, actualCount)
   161  	}
   162  
   163  	if totalFound < actualCount {
   164  		t.Fatalf("Incorrect search total count, got %v\n", totalFound)
   165  	}
   166  }
   167  
   168  func ensureValidOrcidDetails(t *testing.T, orcid *api.OrcidDetails) {
   169  	if emptyField(orcid.Orcid) ||
   170  		emptyField(orcid.URI) ||
   171  		emptyField(orcid.DisplayName) ||
   172  		emptyField(orcid.FirstName) ||
   173  		emptyField(orcid.LastName) {
   174  		log.Printf("%v", orcid)
   175  		t.Fatalf("Expected non-empty field but one is empty\n")
   176  	}
   177  }
   178  
   179  func emptyField(field string) bool {
   180  	return len(strings.TrimSpace(field)) == 0
   181  }
   182  
   183  func loadConfig() config {
   184  
   185  	data, err := ioutil.ReadFile("service_test.yml")
   186  	if err != nil {
   187  		log.Fatal(err)
   188  	}
   189  
   190  	var c config
   191  	if err := yaml.Unmarshal(data, &c); err != nil {
   192  		log.Fatal(err)
   193  	}
   194  
   195  	log.Printf("endpoint  [%s]\n", c.Endpoint)
   196  	log.Printf("secret    [%s]\n", c.Secret)
   197  	return c
   198  }
   199  
   200  func badToken(secret string) string {
   201  
   202  	// Declare the expiration time of the token
   203  	expirationTime := time.Now().Add(-5 * time.Minute)
   204  
   205  	// Create the JWT claims, which includes the username and expiry time
   206  	claims := &jwt.StandardClaims{
   207  		// In JWT, the expiry time is expressed as unix milliseconds
   208  		ExpiresAt: expirationTime.Unix(),
   209  	}
   210  
   211  	// Declare the token with the algorithm used for signing, and the claims
   212  	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
   213  
   214  	// Create the JWT string
   215  	tokenString, err := token.SignedString([]byte(secret))
   216  	if err != nil {
   217  		log.Fatal(err)
   218  	}
   219  	return tokenString
   220  }
   221  
   222  func goodToken(secret string) string {
   223  
   224  	// Declare the expiration time of the token
   225  	expirationTime := time.Now().Add(5 * time.Minute)
   226  
   227  	// Create the JWT claims, which includes the username and expiry time
   228  	claims := &jwt.StandardClaims{
   229  		// In JWT, the expiry time is expressed as unix milliseconds
   230  		ExpiresAt: expirationTime.Unix(),
   231  	}
   232  
   233  	// Declare the token with the algorithm used for signing, and the claims
   234  	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
   235  
   236  	// Create the JWT string
   237  	tokenString, err := token.SignedString([]byte(secret))
   238  	if err != nil {
   239  		log.Fatal(err)
   240  	}
   241  	return tokenString
   242  }
   243  
   244  //
   245  // end of file
   246  //