Ctrl K
ComunidadGuías…

internal/handler/notification_like_handler_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package handler

import (
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestNotificationLikeHandler_LikeNotification_Unauthorized(t *testing.T) {
	handler := &NotificationLikeHandler{}

	req := createTestRequest(http.MethodPost, "/api/notifications/1/like", "")
	rr := httptest.NewRecorder()

	handler.LikeNotification(rr, req)

	assertStatusCode(t, rr, http.StatusUnauthorized)
	assertBodyContains(t, rr, "Unauthorized")
}

func TestNotificationLikeHandler_LikeNotification_InvalidID(t *testing.T) {
	handler := &NotificationLikeHandler{}

	// chi.URLParam returns empty string without router context
	req := createAuthenticatedRequest(http.MethodPost, "/api/notifications/abc/like", "", 1, "test@example.com", "user")
	rr := httptest.NewRecorder()

	handler.LikeNotification(rr, req)

	assertStatusCode(t, rr, http.StatusBadRequest)
	assertBodyContains(t, rr, "Invalid notification ID")
}

func TestNotificationLikeHandler_UnlikeNotification_Unauthorized(t *testing.T) {
	handler := &NotificationLikeHandler{}

	req := createTestRequest(http.MethodDelete, "/api/notifications/1/like", "")
	rr := httptest.NewRecorder()

	handler.UnlikeNotification(rr, req)

	assertStatusCode(t, rr, http.StatusUnauthorized)
	assertBodyContains(t, rr, "Unauthorized")
}

func TestNotificationLikeHandler_UnlikeNotification_InvalidID(t *testing.T) {
	handler := &NotificationLikeHandler{}

	// chi.URLParam returns empty string without router context
	req := createAuthenticatedRequest(http.MethodDelete, "/api/notifications/abc/like", "", 1, "test@example.com", "user")
	rr := httptest.NewRecorder()

	handler.UnlikeNotification(rr, req)

	assertStatusCode(t, rr, http.StatusBadRequest)
	assertBodyContains(t, rr, "Invalid notification ID")
}

func TestNotificationLikeHandler_GetNotificationLikes_InvalidID(t *testing.T) {
	handler := &NotificationLikeHandler{}

	// chi.URLParam returns empty string without router context
	req := createTestRequest(http.MethodGet, "/api/notifications/abc/likes", "")
	rr := httptest.NewRecorder()

	handler.GetNotificationLikes(rr, req)

	assertStatusCode(t, rr, http.StatusBadRequest)
	assertBodyContains(t, rr, "Invalid notification ID")
}

func TestNewNotificationLikeHandler(t *testing.T) {
	handler := NewNotificationLikeHandler(nil)
	if handler == nil {
		t.Error("NewNotificationLikeHandler should return a non-nil handler")
	}
}

// Tests with mock service

func TestNotificationLikeHandler_LikeNotification_Success(t *testing.T) {
	likeService := createTestNotificationLikeService()
	handler := NewNotificationLikeHandler(likeService)

	req := createAuthenticatedRequest(http.MethodPost, "/api/notifications/1/like", "", 1, "admin@example.com", "admin")
	req = addChiURLParam(req, "id", "1")
	rr := httptest.NewRecorder()

	handler.LikeNotification(rr, req)

	assertStatusCode(t, rr, http.StatusCreated)
	assertBodyContains(t, rr, "liked")
}

func TestNotificationLikeHandler_LikeNotification_AlreadyLiked(t *testing.T) {
	likeService := createTestNotificationLikeService()
	handler := NewNotificationLikeHandler(likeService)

	// First like
	req1 := createAuthenticatedRequest(http.MethodPost, "/api/notifications/1/like", "", 1, "admin@example.com", "admin")
	req1 = addChiURLParam(req1, "id", "1")
	rr1 := httptest.NewRecorder()
	handler.LikeNotification(rr1, req1)
	assertStatusCode(t, rr1, http.StatusCreated)

	// Second like - should fail with conflict
	req2 := createAuthenticatedRequest(http.MethodPost, "/api/notifications/1/like", "", 1, "admin@example.com", "admin")
	req2 = addChiURLParam(req2, "id", "1")
	rr2 := httptest.NewRecorder()
	handler.LikeNotification(rr2, req2)

	assertStatusCode(t, rr2, http.StatusConflict)
	assertBodyContains(t, rr2, "already liked")
}

func TestNotificationLikeHandler_UnlikeNotification_Success(t *testing.T) {
	likeService := createTestNotificationLikeService()
	handler := NewNotificationLikeHandler(likeService)

	// First like
	req1 := createAuthenticatedRequest(http.MethodPost, "/api/notifications/1/like", "", 1, "admin@example.com", "admin")
	req1 = addChiURLParam(req1, "id", "1")
	rr1 := httptest.NewRecorder()
	handler.LikeNotification(rr1, req1)

	// Then unlike
	req2 := createAuthenticatedRequest(http.MethodDelete, "/api/notifications/1/like", "", 1, "admin@example.com", "admin")
	req2 = addChiURLParam(req2, "id", "1")
	rr2 := httptest.NewRecorder()
	handler.UnlikeNotification(rr2, req2)

	assertStatusCode(t, rr2, http.StatusNoContent)
}

func TestNotificationLikeHandler_GetNotificationLikes_Success(t *testing.T) {
	likeService := createTestNotificationLikeService()
	handler := NewNotificationLikeHandler(likeService)

	req := createTestRequest(http.MethodGet, "/api/notifications/1/likes", "")
	req = addChiURLParam(req, "id", "1")
	rr := httptest.NewRecorder()

	handler.GetNotificationLikes(rr, req)

	assertStatusCode(t, rr, http.StatusOK)
	assertBodyContains(t, rr, "likes")
	assertBodyContains(t, rr, "count")
}

// Removed 3 panic-expectation tests:
// - TestNotificationLikeHandler_LikeNotification_ValidIDNilService
// - TestNotificationLikeHandler_GetNotificationLikes_ValidIDNilService
// - TestNotificationLikeHandler_UnlikeNotification_ValidIDNilService
// These tests verified nil pointer panics, not business logic.