Files
gocryptotrader/cmd/apichecker/apicheck_test.go
2023-02-22 15:23:18 +11:00

667 lines
15 KiB
Go

package main
import (
"encoding/json"
"os"
"reflect"
"testing"
gctfile "github.com/thrasher-corp/gocryptotrader/common/file"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
"github.com/thrasher-corp/gocryptotrader/log"
)
var (
testAPIKey = ""
testAPIToken = ""
testChecklistID = ""
testCardID = ""
testListID = ""
testBoardID = ""
testBoardName = ""
canTestMainFile = false
)
func TestMain(m *testing.M) {
setTestVars()
err := log.SetGlobalLogConfig(log.GenDefaultSettings())
if err != nil {
log.Error(log.Global, err)
os.Exit(1)
}
log.Infoln(log.Global, "set verbose to true for more detailed output")
configData, err = readFileData(jsonFile)
if err != nil {
log.Error(log.Global, err)
os.Exit(1)
}
testConfigData, err = readFileData(testJSONFile)
if err != nil {
log.Error(log.Global, err)
os.Exit(1)
}
usageData = testConfigData
setTestVars()
testExitCode := m.Run()
err = removeTestFileVars()
if err != nil {
log.Error(log.Global, err)
os.Exit(1)
}
os.Exit(testExitCode)
}
func areTestAPIKeysSet() bool {
return (testAPIKey != "" && testAPIToken != "")
}
func setTestVars() {
if !canUpdateTrello() {
apiKey = testAPIKey
apiToken = testAPIToken
trelloChecklistID = testChecklistID
trelloCardID = testCardID
trelloListID = testListID
trelloBoardID = testBoardID
trelloBoardName = testBoardName
return
}
}
func removeTestFileVars() error {
a, err := readFileData(testJSONFile)
if err != nil {
return err
}
a.BoardID = ""
a.CardID = ""
a.ChecklistID = ""
a.Key = ""
a.ListID = ""
a.Token = ""
file, err := json.MarshalIndent(&a, "", " ")
if err != nil {
return err
}
return os.WriteFile(testJSONFile, file, gctfile.DefaultPermissionOctal)
}
func canTestTrello() bool {
if testAPIKey != "" && testAPIToken != "" && testChecklistID != "" && testCardID != "" && testListID != "" && (testBoardID != "" || testBoardName != "") {
return true
}
return false
}
func TestCheckUpdates(t *testing.T) {
if !canUpdateTrello() || !canTestTrello() {
t.Skip()
}
err := checkUpdates(testJSONFile)
if err != nil {
t.Fatal(err)
}
}
func TestUpdateFile(t *testing.T) {
realConf, err := readFileData(jsonFile)
if err != nil {
t.Fatal(err)
}
configData = realConf
err = updateFile(testJSONFile)
if err != nil {
t.Fatal(err)
}
testConf, err := readFileData(testJSONFile)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(realConf, testConf) {
t.Error("test file update failed")
}
}
func TestCheckExistingExchanges(t *testing.T) {
t.Parallel()
if !checkExistingExchanges("Kraken") {
t.Fatal("Kraken data not found")
}
}
func TestCheckChangeLog(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "h1",
Key: "id",
Val: "revision-history",
TokenDataEnd: "table",
TextTokenData: "td",
DateFormat: "2006/01/02",
RegExp: `^20(\d){2}/(\d){2}/(\d){2}$`,
Path: "https://docs.gemini.com/rest-api/#revision-history"}
if _, err := checkChangeLog(&data); err != nil {
t.Error(err)
}
}
func TestAdd(t *testing.T) {
t.Parallel()
data2 := HTMLScrapingData{
TokenData: "h1",
Key: "id",
Val: "change-log",
TextTokenData: "strong",
TokenDataEnd: "p",
Path: "incorrectpath",
}
err := addExch("FalseName", htmlScrape, data2, false)
if err == nil {
t.Error("expected an error due to invalid path being parsed in")
}
}
func TestHTMLScrapeGemini(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "h1",
Key: "id",
Val: "revision-history",
TokenDataEnd: "table",
TextTokenData: "td",
DateFormat: "2006/01/02",
RegExp: "^20(\\d){2}/(\\d){2}/(\\d){2}$",
CheckString: "2019/11/15",
Path: "https://docs.gemini.com/rest-api/#revision-history"}
_, err := htmlScrapeDefault(&data)
if err != nil {
t.Error(err)
}
}
func TestHTMLScrapeHuobi(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "h1",
Key: "id",
Val: "change-log",
TokenDataEnd: "h2",
TextTokenData: "td",
DateFormat: "2006.01.02 15:04",
RegExp: "^20(\\d){2}.(\\d){2}.(\\d){2} (\\d){2}:(\\d){2}$",
CheckString: "2019.12.27 19:00",
Path: "https://huobiapi.github.io/docs/spot/v1/en/#change-log"}
_, err := htmlScrapeDefault(&data)
if err != nil {
t.Error(err)
}
}
func TestHTMLScrapeCoinbasepro(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "h1",
Key: "id",
Val: "changelog",
TokenDataEnd: "ul",
TextTokenData: "strong",
DateFormat: "01/02/06",
RegExp: "^(\\d){1,2}/(\\d){1,2}/(\\d){2}$",
CheckString: "12/16/19",
Path: "https://docs.pro.coinbase.com/#changelog"}
_, err := htmlScrapeDefault(&data)
if err != nil {
t.Error(err)
}
}
func TestHTMLScrapeBitfinex(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{DateFormat: "2006-01-02",
RegExp: `section-v-(2\d{3}-\d{1,2}-\d{1,2})`,
Path: "https://docs.bitfinex.com/docs/changelog"}
_, err := htmlScrapeBitfinex(&data)
if err != nil {
t.Error(err)
}
}
func TestHTMLScrapeBitmex(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "h4",
Key: "id",
Val: "",
TokenDataEnd: "",
TextTokenData: "",
DateFormat: "Jan-2-2006",
RegExp: `([A-Z]{1}[a-z]{2}-\d{1,2}-2\d{3})`,
Path: "https://www.bitmex.com/static/md/en-US/apiChangelog"}
if _, err := htmlScrapeBitmex(&data); err != nil {
t.Error(err)
}
}
func TestHTMLScrapeHitBTC(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{RegExp: `newest version \d{1}.\d{1}`,
Path: "https://api.hitbtc.com/"}
if _, err := htmlScrapeHitBTC(&data); err != nil {
t.Error(err)
}
}
func TestHTMLScrapeDefault(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "h3",
Key: "id",
Val: "change-change",
TokenDataEnd: "section",
TextTokenData: "p",
DateFormat: "2006-01-02",
RegExp: "(2\\d{3}-\\d{1,2}-\\d{1,2})",
CheckString: "2019-04-28",
Path: "https://www.okcoin.com/docs/en/#change-change"}
_, err := htmlScrapeDefault(&data)
if err != nil {
t.Error(err)
}
}
func TestHTMLScrapeBTSE(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{RegExp: `^version: \d{1}.\d{1}.\d{1}`,
Path: "https://api.btcmarkets.net/openapi/info/index.yaml"}
if _, err := htmlScrapeBTSE(&data); err != nil {
t.Error(err)
}
}
func TestHTMLScrapeBTCMarkets(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{RegExp: `^version: \d{1}.\d{1}.\d{1}`,
Path: "https://api.btcmarkets.net/openapi/info/index.yaml"}
if _, err := htmlScrapeBTCMarkets(&data); err != nil {
t.Error(err)
}
}
func TestHTMLScrapeBitflyer(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "p",
TokenDataEnd: "h3",
TextTokenData: "code",
RegExp: `^https://api.bitflyer.com/v\d{1}/$`,
Path: "https://lightning.bitflyer.com/docs?lang=en"}
if _, err := htmlScrapeBitflyer(&data); err != nil {
t.Error(err)
}
}
func TestHTMLScrapeANX(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{RegExp: `ANX Exchange API v\d{1}`,
Path: "https://anxv3.docs.apiary.io/#reference/quickstart-catalog"}
if _, err := htmlScrapeANX(&data); err != nil {
t.Error(err)
}
}
func TestHTMLPoloniex(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "h1",
Key: "id",
Val: "changelog",
TokenDataEnd: "div",
TextTokenData: "h2",
DateFormat: "2006-01-02",
RegExp: `(2\d{3}-\d{1,2}-\d{1,2})`,
Path: "https://docs.poloniex.com/#changelog"}
if _, err := htmlScrapePoloniex(&data); err != nil {
t.Error(err)
}
}
func TestHTMLItBit(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "a",
Key: "href",
Val: "changelog",
TokenDataEnd: "div",
TextTokenData: "h2",
DateFormat: "2006-01-02",
RegExp: `^https://api.itbit.com/v\d{1}/$`,
Path: "https://api.itbit.com/docs"}
if _, err := htmlScrapeItBit(&data); err != nil {
t.Error(err)
}
}
func TestHTMLScrapeExmo(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{RegExp: `Last updated on [\s\S]*, 20\d{2}`,
Path: "https://exmo.com/en/api/"}
if _, err := htmlScrapeExmo(&data); err != nil {
t.Error(err)
}
}
func TestHTMLBitstamp(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{RegExp: `refer to the v\d{1} API for future references.`,
Path: "https://www.bitstamp.net/api/"}
if _, err := htmlScrapeBitstamp(&data); err != nil {
t.Error(err)
}
}
func TestHTMLKraken(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "h3",
TokenDataEnd: "p",
TextTokenData: "p",
RegExp: `URL: https://api.kraken.com/\d{1}/private/Balance`,
Path: "https://www.kraken.com/features/api"}
if _, err := htmlScrapeKraken(&data); err != nil {
t.Error(err)
}
}
func TestHTMLAlphaPoint(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "h1",
Key: "id",
Val: "introduction",
TokenDataEnd: "blockquote",
TextTokenData: "h3",
RegExp: `revised-calls-\d{1}-\d{1}-\d{1}-gt-\d{1}-\d{1}-\d{1}`,
Path: "https://alphapoint.github.io/slate/#introduction"}
if _, err := htmlScrapeAlphaPoint(&data); err != nil {
t.Error(err)
}
}
func TestHTMLYobit(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "h2",
Key: "id",
Path: "https://www.yobit.net/en/api/"}
if _, err := htmlScrapeYobit(&data); err != nil {
t.Error(err)
}
}
func TestHTMLScrapeOk(t *testing.T) {
t.Parallel()
data := HTMLScrapingData{TokenData: "a",
Key: "href",
Val: "./#change-change",
TokenDataEnd: "./#change-",
RegExp: `./#change-\d{8}`,
Path: "https://www.okx.com/docs/en/"}
if _, err := htmlScrapeOk(&data); err != nil {
t.Error(err)
}
}
func TestUpdate(t *testing.T) {
t.Parallel()
var exchCheck, updatedExch HTMLScrapingData
for x := range configData.Exchanges {
if configData.Exchanges[x].Name == "Exmo" {
exchCheck = *configData.Exchanges[x].Data.HTMLData
}
}
info := ExchangeInfo{Name: "Exmo",
CheckType: "HTML String Check",
Data: &CheckData{HTMLData: &HTMLScrapingData{RegExp: `Last updated on [\s\S]*, 20\d{2}`,
Path: "https://exmo.com/en/api/"},
},
}
updatedExchs := update("Exmo", configData.Exchanges, info)
for y := range updatedExchs {
if updatedExchs[y].Name == "Exmo" {
updatedExch = *updatedExchs[y].Data.HTMLData
}
}
if updatedExch == exchCheck {
t.Fatal("update failed")
}
}
func TestCheckMissingExchanges(t *testing.T) {
t.Parallel()
if a := checkMissingExchanges(); len(a) > len(exchange.Exchanges) {
t.Fatal("invalid response")
}
}
func TestNameUpdates(t *testing.T) {
t.Parallel()
tester := []struct {
Name string
Status string
ExpectedName string
ErrorExpected bool
}{
{
Name: "incorrectname",
Status: "incomplete",
ErrorExpected: true,
},
{
Name: "Gemini 2 2",
Status: "incomplete",
ErrorExpected: false,
},
{
Name: " Gemini 23",
Status: "incomplete",
ErrorExpected: true,
},
{
Name: "Gemini 123",
Status: "complete",
ExpectedName: "Gemini 1",
ErrorExpected: false,
},
{
Name: "Gemini",
Status: "complete",
ExpectedName: "Gemini 1",
ErrorExpected: false,
},
{
Name: "Gemini 24 ",
Status: "incomplete",
ErrorExpected: false,
},
}
for x := range tester {
r, err := nameStateChanges(tester[x].Name, tester[x].Status)
if r != tester[x].ExpectedName && err != nil && !tester[x].ErrorExpected {
t.Errorf("%d failed, expected %v, %v, got: %v, %v\n", x,
tester[x].ExpectedName,
tester[x].ErrorExpected,
r,
err)
}
}
}
func TestReadFileData(t *testing.T) {
t.Parallel()
_, err := readFileData(testJSONFile)
if err != nil {
t.Error(err)
}
}
func TestGetSha(t *testing.T) {
t.Parallel()
_, err := getSha("binance-exchange/binance-official-api-docs")
if err != nil {
t.Error(err)
}
}
func TestCheckBoardID(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip()
}
a, err := trelloCheckBoardID()
if err != nil {
t.Error(err)
}
if a != true {
t.Error("no match found for the given boardID")
}
}
func TestTrelloGetLists(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip()
}
if _, err := trelloGetLists(); err != nil {
t.Error(err)
}
}
func TestGetAllCards(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip()
}
if _, err := trelloGetAllCards(); err != nil {
t.Error(err)
}
}
func TestGetAllChecklists(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip()
}
if _, err := trelloGetAllChecklists(); err != nil {
t.Error(err)
}
}
func TestTrelloGetAllBoards(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip()
}
if trelloBoardID != "" || testBoardName != "" {
t.Skip()
}
if _, err := trelloGetBoardID(); err != nil {
t.Error(err)
}
}
func TestCreateNewList(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip()
}
if err := trelloCreateNewList(); err != nil {
t.Error(err)
}
}
func TestTrelloCreateNewCard(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip()
}
if err := trelloCreateNewCard(); err != nil {
t.Error(err)
}
}
func TestCreateNewChecklist(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip()
}
if err := trelloCreateNewChecklist(); err != nil {
t.Error(err)
}
}
func TestWriteAuthVars(t *testing.T) {
if canTestMainFile {
trelloCardID = "jdsfl"
if err := writeAuthVars(testMode); err != nil {
t.Error(err)
}
}
}
func TestCreateNewCheck(t *testing.T) {
if !canTestTrello() {
t.Skip()
}
err := trelloCreateNewCheck("Gemini")
if err != nil {
t.Error(err)
}
}
func TestUpdateCheckItem(t *testing.T) {
if !canTestTrello() {
t.Skip()
}
a, err := trelloGetChecklistItems()
if err != nil {
t.Error(err)
}
var checkID string
for x := range a.CheckItems {
if a.CheckItems[x].Name == "Gemini 1" {
checkID = a.CheckItems[x].ID
}
}
err = trelloUpdateCheckItem(checkID, "Gemini 1", "incomplete")
if err != nil {
t.Error(err)
}
}
func TestGetChecklistItems(t *testing.T) {
if !canTestTrello() {
t.Skip()
}
_, err := trelloGetChecklistItems()
if err != nil {
t.Error(err)
}
}
func TestSetAuthVars(t *testing.T) {
t.Parallel()
apiKey = ""
configData.Key = ""
apiToken = ""
configData.Token = ""
setAuthVars()
if usageData.Key != "" && usageData.Token != "" {
t.Errorf("incorrect key and token values")
}
}
func TestTrelloDeleteCheckItems(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip()
}
err := trelloDeleteCheckItem("")
if err != nil {
t.Error(err)
}
}
func TestHTMLScrapeBinance(t *testing.T) {
data := HTMLScrapingData{
TokenData: "h1",
Key: "id",
Val: "change-log",
TextTokenData: "strong",
TokenDataEnd: "p",
Path: "https://binance-docs.github.io/apidocs/spot/en/#change-log",
}
_, err := htmlScrapeBinance(&data)
if err != nil {
t.Error(err)
}
}