testutils

package
v0.0.0-...-d8b85fd Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 19, 2025 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package testutils contains helper functions and utilities to assist with running tests. These functions are designed to simplify test setup, teardown, and common tasks required during unit and integration testing in Go.

It includes utilities for mocking, creating test data, and other commonly needed operations that can help make test code more readable, reusable, and maintainable. Example usage:

testutils.NewTestStore(t, db) // Set up a test store that rolls back all changes after a test run.

Index

Constants

This section is empty.

Variables

View Source
var (
	TestPassword   = "C0mpl3x_P@ssw0rD"
	TestProfilePic = "https://fake.link.org/pfp.png"
)

Functions

func CreateTestOrganization

func CreateTestOrganization(ctx context.Context, appStore store.Store, isActive bool, role *models.Role, userID int64) (*models.Organization, error)

func CreateTestOrganizationMember

func CreateTestOrganizationMember(ctx context.Context, appStore store.Store, orgID, roleID, userID int64) (*models.OrganizationMember, error)

func CreateTestRole

func CreateTestRole(ctx context.Context, appStore store.Store, isDeleted bool, orgID int64, permissions []string) (*models.Role, error)

func GenerateDate

func GenerateDate() string

GenerateDate generates a random date in the format "mm/dd/yyyy" using the faker package. The function splits the generated date string (in the format "yyyy-mm-dd") and reformats it to "mm/dd/yyyy" to comply with the desired format.

Returns:

  • A string representing the randomly generated date in "mm/dd/yyyy" format.

Example usage:

date := GenerateDate()
fmt.Println("Generated date:", date) // Output: "03/15/2025"

func GenerateEmailAndUsername

func GenerateEmailAndUsername() (email string, username string)

GenerateEmailAndUsername generates a unique email and username using the faker package. The function uses the faker library to create a random, unique username and then formats it into an email address.

Returns:

  • email: A randomly generated email address formatted as "<username>@clone.meetup.org".
  • username: A randomly generated username. This is used as the local part of the email address.

Example usage:

email, username := GenerateEmailAndUsername()
fmt.Println("Generated email:", email)
fmt.Println("Generated username:", username)

func GenerateTesAuthToken

func GenerateTesAuthToken(authenticator auth.Authenticator, cfg config.AuthConfig, isValid bool, ID int64) (string, error)

func NewTestStore

func NewTestStore(t *testing.T, db *sql.DB) store.Store

NewTestStore sets up a test store for running tests that interacts with a real database. It ensures that all changes made during the test are rolled back after the test completes. This is achieved by using a database transaction, so any database modifications (inserts, updates, deletes) performed during the test will not persist beyond the test run.

Parameters:

  • t (testing.T): The test instance provided by the testing framework, used for managing test state.
  • db (*sql.DB): The database connection to be used by the test store.

Returns:

  • store.Store: A store instance configured for testing. It uses transactions that will be rolled back after the test completes.

Example usage:

func TestCreateUser(t *testing.T) {
    testStore := NewTestStore(t, db)
    // Use testStore to interact with the database during the test
    // At the end of the test, all changes to the database will be rolled back

Types

type ClaimsDetails

type ClaimsDetails struct {
	Sub       int64
	Exp       int64
	IssuedAt  int64
	NotBefore int64
}

type TestRequestData

type TestRequestData map[string]any

TestRequestData represents the request payload for a test HTTP request. It uses a flexible map structure to allow arbitrary key-value pairs for building request bodies.

type TestRequestHeaders

type TestRequestHeaders map[string]string

TestRequestHeaders represents a collection of HTTP headers for test requests. It is a map where the key is the header name and the value is the header value.

Example:

headers := TestRequestHeaders{
  "Authorization": "Bearer some.jwt.token",
  "Content-Type":  "application/json",
}

type TestRequestResponse

type TestRequestResponse struct {
	Response     *httptest.ResponseRecorder
	ResponseData TestResponseData
}

TestRequestResponse wraps the result of an HTTP test request. It includes the raw response recorder and the parsed response data.

Fields:

  • Response (*httptest.ResponseRecorder): Captures the HTTP response for status, headers, and body.
  • ResponseData (TestResponseData): The decoded JSON response body.

func RunTestRequest

func RunTestRequest(mux http.Handler, method, endpoint string, headers TestRequestHeaders, data TestRequestData) (*TestRequestResponse, error)

RunTestRequest performs a test HTTP request and returns the result.

It marshals the provided request data to JSON, sets the appropriate content type, and executes the request against the given HTTP handler (mux). The function then captures the response and unmarshals the JSON response body for easier assertions.

Parameters:

  • mux (http.Handler): The HTTP handler to serve the request (e.g., your router).
  • method (string): The HTTP method to use (e.g., "GET", "POST", "PUT", "DELETE").
  • endpoint (string): The API endpoint to test (e.g., "/api/login").
  • headers (TestRequestHeaders): The headers to include in the request (e.g., authorization, content type).
  • data (TestRequestData): The request payload, which will be marshaled to JSON.

Returns:

  • *TestRequestResponse: Contains the HTTP response recorder and the parsed response data.
  • error: An error if request creation, execution, or response decoding fails.

Example usage:

		res, err := RunTestRequest(
         router, "/login", "POST",
         TestRequestHeaders{"Authorization": "Bearer some.jwt.token"},
	     TestRequestData{
		   "email": "test@example.com",
		   "password": "password123",
	     })
		if err != nil {
		  log.Fatal(err)
		}
		fmt.Println(res.Response.Code)               // prints the HTTP status code
		fmt.Println(res.ResponseData["message"])     // prints the response message

func (*TestRequestResponse) GetData

func (r *TestRequestResponse) GetData() (map[string]any, bool)

GetData extracts the "data" field from the response data.

This method returns the response data as a map, along with a boolean indicating success. If the "data" field isn't present or isn't a map, it returns false.

Returns:

  • map[string]any: The data from the response.
  • bool: True if the "data" field was found and is a map, false otherwise.

Example usage:

res, _ := RunTestRequest(router, "GET", "/profile", nil, nil)
if data, ok := res.GetData(); ok {
  fmt.Println(data) // prints the response data
}

func (*TestRequestResponse) GetErrorMessages

func (r *TestRequestResponse) GetErrorMessages() (map[string]any, bool)

GetErrorMessages extracts the "errors" field from the response data.

This method returns the error messages as a map, along with a boolean indicating success. If the "errors" field isn't present or isn't a map, it returns false.

Returns:

  • map[string]any: The error messages from the response.
  • bool: True if the "errors" field was found and is a map, false otherwise.

Example usage:

res, _ := RunTestRequest(router, "POST", "/register", nil, requestData)
if errors, ok := res.GetErrorMessages(); ok {
  fmt.Println(errors) // prints the error messages
}

func (*TestRequestResponse) GetMessage

func (r *TestRequestResponse) GetMessage() string

GetMessage extracts the "message" field from the response data.

This method checks if the "message" field exists and is a string. If the field is missing or not a string, it returns an empty string.

Returns:

  • string: The message string from the response, or an empty string if not found or invalid.

Example usage:

res, _ := RunTestRequest(router, "POST", "/login", nil, requestData)
fmt.Println(res.GetMessage()) // prints the message from the response, or an empty string

func (*TestRequestResponse) StatusCode

func (r *TestRequestResponse) StatusCode() int

StatusCode returns the HTTP status code from the response.

This method provides a convenient way to access the status code of the test HTTP response. If the response is nil, it returns nil to avoid panics.

Returns:

  • *int: A pointer to the status code, or nil if the response is not set.

Example usage:

res, _ := RunTestRequest(router, "GET", "/users", nil, nil)
if statusCode := res.StatusCode(); statusCode != nil {
  fmt.Println(*statusCode)  // prints the HTTP status code
}

type TestResponseData

type TestResponseData map[string]any

TestResponseData represents the response body of a test HTTP request. Like the request, it uses a map to handle dynamic response structures.

type TestUserData

type TestUserData struct {
	Email    string
	Username string
	Password string
	Activate bool
}

TestUserData holds the data required to create a test user. It is typically used for setting up mock or test user data in unit tests or integration tests.

Fields:

  • Email: The email address of the test user. This field is used to create a user in the system, and should be unique for each test case.
  • Username: The username for the test user. It can be any string value used in the user creation process.
  • Password: The password for the test user. This should be a valid password string used for testing login and authentication logic.
  • Activate: A boolean flag indicating whether the user should be activated upon creation. If true, the user will be marked as activated; otherwise, they will remain inactive.

Example usage:

testData := TestUserData{
  Email:    "testuser@example.com",
  Username: "testuser",
  Password: "securePassword123",
  Activate: true,
}

func NewTestUserData

func NewTestUserData(activate bool) TestUserData

NewTestUserData generates a new instance of TestUserData with a random email, username, a predefined test password, and an activation status based on the `activate` argument.

This function utilizes the `GenerateEmailAndUsername` function to generate a unique email and username, and sets a default test password (`TestPassword`) while allowing the caller to specify whether the user should be activated or not.

Parameters:

  • activate (bool): A flag indicating whether the user should be activated or not.

Returns:

  • A `TestUserData` struct populated with the generated email, username, password, and activation status.

Example usage:

userData := NewTestUserData(true)
fmt.Println(userData.Email, userData.Username, userData.Activate)

func (TestUserData) CreateDeactivatedTestUser

func (c TestUserData) CreateDeactivatedTestUser(ctx context.Context, store store.Store, role models.UserRole) (*models.User, error)

CreateDeactivatedTestUser creates a new user with a deactivated state for testing purposes. The user is created with the specified details, and the `IsActive` field is set to `false`. The `ActivatedAt` field is set to `time.Now()` to simulate a deactivated user.

Parameters:

  • ctx (context.Context): The context for managing cancellation and deadlines.
  • store (store.Store): The store object that handles the interaction with the database.

Returns:

  • *models.User: The created user object with the deactivated state.
  • error: An error if the user creation fails, or nil if the creation is successful.

func (TestUserData) CreateTestUser

func (c TestUserData) CreateTestUser(ctx context.Context, appStore store.Store, role models.UserRole) (*models.User, *models.UserProfile, error)

CreateTestUser creates a test user and their associated profile in the database using the provided store. The method interacts with the `store` to save the user and user profile data, returning the created `User` and `UserProfile` models along with any errors encountered during the process.

Parameters:

  • ctx (context.Context): The context to associate with the database operation.
  • store (store.Store): The store instance used to interact with the database to create the user and profile.

Returns:

  • *models.User: The created `User` model.
  • *models.UserProfile: The created `UserProfile` model.
  • error: Any error that occurred during the creation process, or nil if successful.

Example usage:

userData := NewTestUserData(true)
user, profile, err := userData.CreateTestUser(ctx, store)
if err != nil {
    log.Fatal(err)
}
fmt.Println("User created:", user, "Profile created:", profile)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL