226 lines
5.4 KiB
Go
226 lines
5.4 KiB
Go
![]() |
package perspective
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"testing"
|
||
|
|
||
|
"4vif5i.gitea.cloud/numenor-labs/discourse/backend/ipfs"
|
||
|
"github.com/go-redis/redismock/v8"
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
"gorm.io/driver/sqlite"
|
||
|
"gorm.io/gorm"
|
||
|
)
|
||
|
|
||
|
// Setup test dependencies
|
||
|
func setupTestDependencies(t *testing.T) (*PerspectiveService, redismock.ClientMock) {
|
||
|
// Setup mock Redis
|
||
|
client, mock := redismock.NewClientMock()
|
||
|
|
||
|
// Setup in-memory SQLite database
|
||
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
||
|
if err != nil {
|
||
|
t.Fatalf("Failed to open in-memory database: %v", err)
|
||
|
}
|
||
|
|
||
|
// Create a mock IPFS service
|
||
|
ipfsService := ipfs.NewMockIPFSService()
|
||
|
|
||
|
// Create the service with our mocks
|
||
|
service := NewPerspectiveService(client, db, ipfsService)
|
||
|
|
||
|
return service, mock
|
||
|
}
|
||
|
|
||
|
func TestSubmitPerspective_Success(t *testing.T) {
|
||
|
service, mock := setupTestDependencies(t)
|
||
|
ctx := context.Background()
|
||
|
|
||
|
// Setup Redis mock expectations for unverified user
|
||
|
mock.ExpectExists("user:0x1234:submissions").SetVal(0)
|
||
|
mock.ExpectSet("user:0x1234:submissions", 1, RedisTTL).SetVal("OK")
|
||
|
|
||
|
// Call the service method
|
||
|
ipfsHash, err := service.SubmitPerspective(
|
||
|
ctx,
|
||
|
"issue123",
|
||
|
"This is a test perspective",
|
||
|
"",
|
||
|
"0x1234",
|
||
|
false,
|
||
|
ValidCaptchaToken,
|
||
|
)
|
||
|
|
||
|
// Verify the results
|
||
|
assert.NoError(t, err)
|
||
|
assert.NotEmpty(t, ipfsHash)
|
||
|
|
||
|
// Verify Redis mock expectations were met
|
||
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||
|
t.Errorf("Redis expectations were not met: %v", err)
|
||
|
}
|
||
|
|
||
|
// Verify perspective was stored in the database
|
||
|
var perspective Perspective
|
||
|
err = service.db.Where("ipfs_hash = ?", ipfsHash).First(&perspective).Error
|
||
|
assert.NoError(t, err)
|
||
|
assert.Equal(t, "issue123", perspective.IssueID)
|
||
|
assert.Equal(t, "0x1234", perspective.UserAddress)
|
||
|
assert.Equal(t, false, perspective.IsVerified)
|
||
|
}
|
||
|
|
||
|
func TestSubmitPerspective_VerifiedUser(t *testing.T) {
|
||
|
service, mock := setupTestDependencies(t)
|
||
|
ctx := context.Background()
|
||
|
|
||
|
// No need to mock Redis for verified user
|
||
|
|
||
|
// Call the service method
|
||
|
ipfsHash, err := service.SubmitPerspective(
|
||
|
ctx,
|
||
|
"issue123",
|
||
|
"This is a test perspective from a verified user",
|
||
|
"",
|
||
|
"0x5678",
|
||
|
true, // Verified user
|
||
|
"", // No captcha needed
|
||
|
)
|
||
|
|
||
|
// Verify the results
|
||
|
assert.NoError(t, err)
|
||
|
assert.NotEmpty(t, ipfsHash)
|
||
|
|
||
|
// Verify Redis mock expectations were met
|
||
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||
|
t.Errorf("Redis expectations were not met: %v", err)
|
||
|
}
|
||
|
|
||
|
// Verify perspective was stored in the database
|
||
|
var perspective Perspective
|
||
|
err = service.db.Where("ipfs_hash = ?", ipfsHash).First(&perspective).Error
|
||
|
assert.NoError(t, err)
|
||
|
assert.Equal(t, "issue123", perspective.IssueID)
|
||
|
assert.Equal(t, "0x5678", perspective.UserAddress)
|
||
|
assert.Equal(t, true, perspective.IsVerified)
|
||
|
}
|
||
|
|
||
|
func TestSubmitPerspective_RateLimit(t *testing.T) {
|
||
|
service, mock := setupTestDependencies(t)
|
||
|
ctx := context.Background()
|
||
|
|
||
|
// Setup Redis mock expectations for rate-limited user
|
||
|
mock.ExpectGet("user:0x1234:submissions").SetVal("5") // Rate limit reached
|
||
|
|
||
|
// Call the service method
|
||
|
_, err := service.SubmitPerspective(
|
||
|
ctx,
|
||
|
"issue123",
|
||
|
"This is a test perspective that should be rate limited",
|
||
|
"",
|
||
|
"0x1234",
|
||
|
false,
|
||
|
ValidCaptchaToken,
|
||
|
)
|
||
|
|
||
|
// Verify the results
|
||
|
assert.Error(t, err)
|
||
|
assert.Contains(t, err.Error(), "rate limit exceeded")
|
||
|
|
||
|
// Verify Redis mock expectations were met
|
||
|
if err := mock.ExpectationsWereMet(); err != nil {
|
||
|
t.Errorf("Redis expectations were not met: %v", err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestSubmitPerspective_InvalidCaptcha(t *testing.T) {
|
||
|
service, _ := setupTestDependencies(t)
|
||
|
ctx := context.Background()
|
||
|
|
||
|
// Call the service method with invalid captcha
|
||
|
_, err := service.SubmitPerspective(
|
||
|
ctx,
|
||
|
"issue123",
|
||
|
"This is a test perspective with invalid captcha",
|
||
|
"",
|
||
|
"0x1234",
|
||
|
false,
|
||
|
"invalid-token",
|
||
|
)
|
||
|
|
||
|
// Verify the results
|
||
|
assert.Error(t, err)
|
||
|
assert.Contains(t, err.Error(), "invalid CAPTCHA token")
|
||
|
}
|
||
|
|
||
|
func TestSubmitPerspective_OversizedText(t *testing.T) {
|
||
|
service, _ := setupTestDependencies(t)
|
||
|
ctx := context.Background()
|
||
|
|
||
|
// Generate a text that exceeds the maximum length
|
||
|
oversizedText := ""
|
||
|
for i := 0; i < MaxTextLength+100; i++ {
|
||
|
oversizedText += "a"
|
||
|
}
|
||
|
|
||
|
// Call the service method with oversized text
|
||
|
_, err := service.SubmitPerspective(
|
||
|
ctx,
|
||
|
"issue123",
|
||
|
oversizedText,
|
||
|
"",
|
||
|
"0x1234",
|
||
|
true,
|
||
|
"",
|
||
|
)
|
||
|
|
||
|
// Verify the results
|
||
|
assert.Error(t, err)
|
||
|
assert.Contains(t, err.Error(), "exceeds maximum length")
|
||
|
}
|
||
|
|
||
|
func TestGetPerspectivesByIssue(t *testing.T) {
|
||
|
service, _ := setupTestDependencies(t)
|
||
|
ctx := context.Background()
|
||
|
|
||
|
// Insert test perspectives for the issue
|
||
|
testIssueID := "issue456"
|
||
|
|
||
|
// Create and store a few test perspectives
|
||
|
for i := 0; i < 3; i++ {
|
||
|
ipfsHash, err := service.SubmitPerspective(
|
||
|
ctx,
|
||
|
testIssueID,
|
||
|
"Test perspective",
|
||
|
"",
|
||
|
"0xABCD",
|
||
|
true,
|
||
|
"",
|
||
|
)
|
||
|
assert.NoError(t, err)
|
||
|
assert.NotEmpty(t, ipfsHash)
|
||
|
}
|
||
|
|
||
|
// Also create a perspective for a different issue
|
||
|
_, err := service.SubmitPerspective(
|
||
|
ctx,
|
||
|
"different-issue",
|
||
|
"Different issue perspective",
|
||
|
"",
|
||
|
"0xABCD",
|
||
|
true,
|
||
|
"",
|
||
|
)
|
||
|
assert.NoError(t, err)
|
||
|
|
||
|
// Get perspectives for the test issue
|
||
|
perspectives, err := service.GetPerspectivesByIssue(testIssueID)
|
||
|
|
||
|
// Verify the results
|
||
|
assert.NoError(t, err)
|
||
|
assert.Len(t, perspectives, 3) // Should only find the 3 perspectives for this issue
|
||
|
|
||
|
// Verify each perspective has the correct issue ID
|
||
|
for _, p := range perspectives {
|
||
|
assert.Equal(t, testIssueID, p.IssueID)
|
||
|
}
|
||
|
}
|