github.com/DapperCollectives/CAST/backend@v0.0.0-20230921221157-1350c8be7c96/tests/main_test.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"io/ioutil"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"os"
     9  	"testing"
    10  
    11  	"github.com/DapperCollectives/CAST/backend/main/server"
    12  	"github.com/DapperCollectives/CAST/backend/main/shared"
    13  	utils "github.com/DapperCollectives/CAST/backend/tests/test_utils"
    14  	"github.com/bjartek/overflow/overflow"
    15  	"github.com/joho/godotenv"
    16  	"github.com/rs/zerolog/log"
    17  )
    18  
    19  var A server.App
    20  var O *overflow.OverflowState
    21  var otu *utils.OverflowTestUtils
    22  
    23  const ServiceAddress = "0xf8d6e0586b0a20c7"
    24  
    25  type errorResponse struct {
    26  	StatusCode int		`json:"statusCode,string"`
    27  	ErrorCode  string	`json:"errorCode"`
    28  	Message    string	`json:"message"`
    29  	Details    string	`json:"details"`
    30  }
    31  
    32  var (
    33  	errIncompleteRequest = errorResponse{
    34  		StatusCode: http.StatusBadRequest,
    35  		ErrorCode:  "ERR_1001",
    36  		Message:    "Error",
    37  		Details:    "There was an error trying to complete your request",
    38  	}
    39  
    40  	errCreateCommunity = errorResponse{
    41  		StatusCode: http.StatusBadRequest,
    42  		ErrorCode:  "ERR_1002",
    43  		Message:    "Error",
    44  		Details:    "There was an error trying to create your community",
    45  	}
    46  
    47  	errFetchingBalance = errorResponse{
    48  		StatusCode: http.StatusBadRequest,
    49  		ErrorCode:  "ERR_1003",
    50  		Message:    "Error Fetching Balance",
    51  		Details: `While confirming your balance, we've encountered an error
    52  							connecting to the Flow Blockchain.`,
    53  	}
    54  
    55  	errInsufficientBalance = errorResponse{
    56  		StatusCode: http.StatusUnauthorized,
    57  		ErrorCode:  "ERR_1004",
    58  		Message:    "Insufficient Balance",
    59  		Details: `In order to vote on this proposal you must have a minimum 
    60  							balance of %f %s tokens in your wallet.`,
    61  	}
    62  
    63  	errForbidden = errorResponse{
    64  		StatusCode: http.StatusForbidden,
    65  		ErrorCode:  "ERR_1005",
    66  		Message:    "Forbidden",
    67  		Details:    "You are not authorized to perform this action.",
    68  	}
    69  
    70  	errCreateProposal = errorResponse{
    71  		StatusCode: http.StatusForbidden,
    72  		ErrorCode:  "ERR_1006",
    73  		Message:    "Error",
    74  		Details:    "There was an error trying to create your proposal",
    75  	}
    76  
    77  	errUpdateCommunity = errorResponse{
    78  		StatusCode: http.StatusForbidden,
    79  		ErrorCode:  "ERR_1007",
    80  		Message:    "Error",
    81  		Details:    "There was an error trying to update your community",
    82  	}
    83  
    84  	errStrategyNotFound = errorResponse{
    85  		StatusCode: http.StatusNotFound,
    86  		ErrorCode:  "ERR_1008",
    87  		Message:    "Strategy Not Found",
    88  		Details:    "The strategy name you are trying to use no longer exists.",
    89  	}
    90  
    91  	errAlreadyVoted = errorResponse{
    92  		StatusCode: http.StatusBadRequest,
    93  		ErrorCode:  "ERR_1009",
    94  		Message:    "Error",
    95  		Details:    "Address %s has already voted for proposal %d.",
    96  	}
    97  
    98  	errInactiveProposal = errorResponse{
    99  		StatusCode: http.StatusBadRequest,
   100  		ErrorCode:  "ERR_1010",
   101  		Message:    "Error",
   102  		Details:    "Cannot vote on an inactive proposal.",
   103  	}
   104  
   105  	errGetCommunity = errorResponse{
   106  		StatusCode: http.StatusInternalServerError,
   107  		ErrorCode:  "ERR_1011",
   108  		Message:    "Error",
   109  		Details:    "There was an error retrieving the community.",
   110  	}
   111  
   112  	errCreateVote = errorResponse{
   113  		StatusCode: http.StatusInternalServerError,
   114  		ErrorCode:  "ERR_1012",
   115  		Message:    "Error",
   116  		Details:    "There was an error creating the vote.",
   117  	}
   118  
   119  	nilErr = errorResponse{}
   120  )
   121  
   122  func TestMain(m *testing.M) {
   123  	var err error
   124  
   125  	emulator := overflow.NewOverflowEmulator()
   126  	emulator.Config("./flow.json")
   127  	emulator.BasePath("./main/cadence")
   128  	O = emulator.Start()
   129  
   130  	CWD := "../"
   131  	os.Setenv("CWD", CWD)
   132  
   133  	// Load .env file if ENV_NAME is not set (i.e. locally)
   134  	if UseDotEnv := os.Getenv("ENV_NAME"); len(UseDotEnv) == 0 {
   135  		err = godotenv.Load(CWD + ".env")
   136  	}
   137  	if err != nil {
   138  		log.Fatal().Err(err).Msg("Error loading .env file")
   139  	}
   140  
   141  	os.Chdir(CWD)
   142  	os.Unsetenv("FVT_FEATURES")
   143  	os.Setenv("FLOW_ENV", "emulator")
   144  
   145  	A.Initialize()
   146  
   147  	// Load custom scripts for strategies
   148  	scripts, err := ioutil.ReadFile("../main/cadence/scripts/custom/scripts.json")
   149  	if err != nil {
   150  		log.Error().Err(err).Msg("Error Reading Custom Strategy scripts.")
   151  	}
   152  
   153  	var customScripts []shared.CustomScript
   154  	err = json.Unmarshal(scripts, &customScripts)
   155  	if err != nil {
   156  		log.Error().Err(err).Msg("Error during Unmarshalling custom scripts")
   157  	}
   158  
   159  	var customScriptsMap = make(map[string]shared.CustomScript)
   160  	for _, script := range customScripts {
   161  		customScriptsMap[script.Key] = script
   162  	}
   163  
   164  	adapter := shared.NewFlowClient(os.Getenv("FLOW_ENV"), customScriptsMap)
   165  
   166  	// Setup overflow test utils struct
   167  	otu = &utils.OverflowTestUtils{T: nil, A: &A, O: O, Adapter: adapter}
   168  
   169  	ensureTableExists()
   170  	// Clear DB tables before running tests
   171  	clearTable("communities")
   172  	clearTable("proposals")
   173  	clearTable("community_users")
   174  	clearTable("votes")
   175  	clearTable("balances")
   176  	clearTable("lists")
   177  	code := m.Run()
   178  	// Clear DB tables after running tests
   179  	// clearTable("communities")
   180  	// clearTable("proposals")
   181  	// clearTable("votes")
   182  	// clearTable("community_users")
   183  	os.Exit(code)
   184  }
   185  
   186  const tableCreationQuery = `
   187    CREATE TABLE IF NOT EXISTS communities (
   188      id BIGSERIAL primary key,
   189      name VARCHAR(256) not null,
   190      body TEXT,
   191      logo VARCHAR(256),
   192      cid VARCHAR(64),
   193      created_at TIMESTAMP default now()
   194    )
   195  `
   196  
   197  func ensureTableExists() {
   198  	if _, err := A.DB.Conn.Exec(A.DB.Context, tableCreationQuery); err != nil {
   199  		log.Fatal().Err(err)
   200  	}
   201  }
   202  
   203  func clearTable(name string) {
   204  	log.Debug().Msgf("Clearing DB table: %s", name)
   205  	A.DB.Conn.Exec(A.DB.Context, "TRUNCATE "+name+" RESTART IDENTITY CASCADE")
   206  }
   207  
   208  // HTTP Stuff
   209  
   210  func executeRequest(req *http.Request) *httptest.ResponseRecorder {
   211  	rr := httptest.NewRecorder()
   212  	A.Router.ServeHTTP(rr, req)
   213  
   214  	return rr
   215  }
   216  
   217  func checkResponseCode(t *testing.T, expected, actual int) {
   218  	if expected != actual {
   219  		t.Errorf("Expected response code %d. Got %d\n", expected, actual)
   220  	}
   221  }
   222  
   223  func CheckResponseCode(t *testing.T, expected, actual int) {
   224  	if expected != actual {
   225  		t.Errorf("Expected response code %d. Got %d\n", expected, actual)
   226  	}
   227  }