mirror of
https://github.com/greedychipmunk/agent-skills.git
synced 2026-09-14 20:46:42 +08:00
488 lines
14 KiB
JavaScript
488 lines
14 KiB
JavaScript
/**
|
|
* CONTROLLER TEST TEMPLATE
|
|
*
|
|
* Comprehensive Jasmine/Jest test template for AngularJS controllers.
|
|
* Demonstrates best practices for controller testing including:
|
|
* - Setup and teardown
|
|
* - Scope initialization
|
|
* - Method testing
|
|
* - Event handling
|
|
* - HTTP interactions
|
|
* - Error handling
|
|
*
|
|
* Usage:
|
|
* 1. Replace 'UserController' with your controller name
|
|
* 2. Replace test method names with actual controller methods
|
|
* 3. Add specific test cases for your controller logic
|
|
* 4. Keep test structure for maintainability
|
|
*/
|
|
|
|
// ============================================================================
|
|
// JASMINE VERSION
|
|
// ============================================================================
|
|
|
|
describe("UserController (Jasmine)", function () {
|
|
var $controller, $scope, $q, $httpBackend, $timeout;
|
|
var UserService, AuthService;
|
|
var UserController;
|
|
|
|
/**
|
|
* Load the application module and define the controller
|
|
*/
|
|
beforeEach(module("myApp"));
|
|
|
|
/**
|
|
* Setup test dependencies using $provide to mock services
|
|
*/
|
|
beforeEach(
|
|
module(function ($provide) {
|
|
// Mock UserService
|
|
$provide.value("UserService", {
|
|
getUsers: jasmine.createSpy("getUsers").and.returnValue([]),
|
|
getUserById: jasmine.createSpy("getUserById").and.returnValue(null),
|
|
saveUser: jasmine.createSpy("saveUser").and.returnValue(true),
|
|
deleteUser: jasmine.createSpy("deleteUser").and.returnValue(true),
|
|
});
|
|
|
|
// Mock AuthService
|
|
$provide.value("AuthService", {
|
|
isAuthenticated: jasmine
|
|
.createSpy("isAuthenticated")
|
|
.and.returnValue(true),
|
|
getCurrentUser: jasmine.createSpy("getCurrentUser").and.returnValue({
|
|
id: 1,
|
|
name: "Current User",
|
|
}),
|
|
logout: jasmine.createSpy("logout"),
|
|
});
|
|
})
|
|
);
|
|
|
|
/**
|
|
* Inject and initialize test fixtures
|
|
*/
|
|
beforeEach(inject(function (
|
|
_$controller_,
|
|
_$rootScope_,
|
|
_$q_,
|
|
_$httpBackend_,
|
|
_$timeout_,
|
|
_UserService_,
|
|
_AuthService_
|
|
) {
|
|
$controller = _$controller_;
|
|
$scope = _$rootScope_.$new();
|
|
$q = _$q_;
|
|
$httpBackend = _$httpBackend_;
|
|
$timeout = _$timeout_;
|
|
UserService = _UserService_;
|
|
AuthService = _AuthService_;
|
|
|
|
// Create controller instance
|
|
UserController = $controller("UserController", {
|
|
$scope: $scope,
|
|
UserService: UserService,
|
|
AuthService: AuthService,
|
|
});
|
|
}));
|
|
|
|
/**
|
|
* Clean up after each test
|
|
*/
|
|
afterEach(function () {
|
|
$httpBackend.verifyNoOutstandingExpectation();
|
|
$httpBackend.verifyNoOutstandingRequest();
|
|
});
|
|
|
|
// ==========================================================================
|
|
// INITIALIZATION TESTS
|
|
// ==========================================================================
|
|
|
|
describe("Controller Initialization", function () {
|
|
it("should initialize with default values", function () {
|
|
expect(UserController).toBeDefined();
|
|
expect($scope.users).toBeDefined();
|
|
expect($scope.loading).toBe(false);
|
|
expect($scope.error).toBeNull();
|
|
});
|
|
|
|
it("should load users on initialization", function () {
|
|
UserService.getUsers.and.returnValue([
|
|
{ id: 1, name: "User 1" },
|
|
{ id: 2, name: "User 2" },
|
|
]);
|
|
|
|
var result = UserController.loadUsers();
|
|
expect(UserService.getUsers).toHaveBeenCalled();
|
|
expect($scope.users).toBeDefined();
|
|
});
|
|
|
|
it("should check authentication on initialization", function () {
|
|
expect(AuthService.isAuthenticated).toHaveBeenCalled();
|
|
expect($scope.currentUser).toBeDefined();
|
|
});
|
|
});
|
|
|
|
// ==========================================================================
|
|
// METHOD TESTS
|
|
// ==========================================================================
|
|
|
|
describe("UserController.loadUsers()", function () {
|
|
it("should fetch users from service", function () {
|
|
var mockUsers = [
|
|
{ id: 1, name: "John", email: "john@example.com" },
|
|
{ id: 2, name: "Jane", email: "jane@example.com" },
|
|
];
|
|
|
|
UserService.getUsers.and.returnValue(mockUsers);
|
|
|
|
UserController.loadUsers();
|
|
|
|
expect(UserService.getUsers).toHaveBeenCalled();
|
|
expect($scope.users).toEqual(mockUsers);
|
|
expect($scope.error).toBeNull();
|
|
});
|
|
|
|
it("should set loading state during fetch", function () {
|
|
var deferred = $q.defer();
|
|
UserService.getUsers.and.returnValue(deferred.promise);
|
|
|
|
$scope.loading = false;
|
|
UserController.loadUsers();
|
|
expect($scope.loading).toBe(true);
|
|
|
|
deferred.resolve([]);
|
|
$scope.$apply();
|
|
expect($scope.loading).toBe(false);
|
|
});
|
|
|
|
it("should handle loading errors gracefully", function () {
|
|
var deferred = $q.defer();
|
|
UserService.getUsers.and.returnValue(deferred.promise);
|
|
|
|
UserController.loadUsers();
|
|
deferred.reject("API Error");
|
|
$scope.$apply();
|
|
|
|
expect($scope.error).toBe("API Error");
|
|
expect($scope.users).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe("UserController.selectUser()", function () {
|
|
it("should set selected user", function () {
|
|
var user = { id: 1, name: "John" };
|
|
$scope.selectedUser = null;
|
|
|
|
UserController.selectUser(user);
|
|
|
|
expect($scope.selectedUser).toEqual(user);
|
|
});
|
|
|
|
it("should fetch user details", function () {
|
|
var user = { id: 1, name: "John" };
|
|
UserService.getUserById.and.returnValue(user);
|
|
|
|
UserController.selectUser(user);
|
|
|
|
expect(UserService.getUserById).toHaveBeenCalledWith(1);
|
|
expect($scope.selectedUser).toEqual(user);
|
|
});
|
|
|
|
it("should handle null user", function () {
|
|
UserController.selectUser(null);
|
|
expect($scope.selectedUser).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("UserController.saveUser()", function () {
|
|
it("should save user data", function () {
|
|
$scope.user = { id: 1, name: "John", email: "john@example.com" };
|
|
UserService.saveUser.and.returnValue(true);
|
|
|
|
UserController.saveUser();
|
|
|
|
expect(UserService.saveUser).toHaveBeenCalledWith($scope.user);
|
|
});
|
|
|
|
it("should clear form after successful save", function () {
|
|
$scope.user = { id: 1, name: "John" };
|
|
UserService.saveUser.and.returnValue(true);
|
|
|
|
UserController.saveUser();
|
|
|
|
expect($scope.user).toEqual({});
|
|
expect($scope.error).toBeNull();
|
|
});
|
|
|
|
it("should display error on save failure", function () {
|
|
$scope.user = { id: 1, name: "John" };
|
|
UserService.saveUser.and.returnValue(false);
|
|
|
|
UserController.saveUser();
|
|
|
|
expect($scope.error).toBe("Failed to save user");
|
|
});
|
|
|
|
it("should validate required fields before save", function () {
|
|
$scope.user = { name: "", email: "" };
|
|
|
|
UserController.saveUser();
|
|
|
|
expect(UserService.saveUser).not.toHaveBeenCalled();
|
|
expect($scope.error).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe("UserController.deleteUser()", function () {
|
|
it("should delete user with confirmation", function () {
|
|
$scope.selectedUser = { id: 1, name: "John" };
|
|
spyOn(window, "confirm").and.returnValue(true);
|
|
|
|
UserController.deleteUser();
|
|
|
|
expect(window.confirm).toHaveBeenCalled();
|
|
expect(UserService.deleteUser).toHaveBeenCalledWith(1);
|
|
});
|
|
|
|
it("should not delete without confirmation", function () {
|
|
$scope.selectedUser = { id: 1, name: "John" };
|
|
spyOn(window, "confirm").and.returnValue(false);
|
|
|
|
UserController.deleteUser();
|
|
|
|
expect(UserService.deleteUser).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("should refresh list after successful delete", function () {
|
|
$scope.selectedUser = { id: 1, name: "John" };
|
|
$scope.users = [
|
|
{ id: 1, name: "John" },
|
|
{ id: 2, name: "Jane" },
|
|
];
|
|
spyOn(window, "confirm").and.returnValue(true);
|
|
UserService.deleteUser.and.returnValue(true);
|
|
|
|
UserController.deleteUser();
|
|
|
|
expect($scope.users.length).toBeLessThan(2);
|
|
expect($scope.selectedUser).toBeNull();
|
|
});
|
|
});
|
|
|
|
// ==========================================================================
|
|
// EVENT HANDLING TESTS
|
|
// ==========================================================================
|
|
|
|
describe("UserController Event Handling", function () {
|
|
it("should handle user:updated event", function () {
|
|
var updatedUser = { id: 1, name: "Updated User" };
|
|
spyOn(UserController, "loadUsers");
|
|
|
|
$scope.$broadcast("user:updated", updatedUser);
|
|
|
|
expect(UserController.loadUsers).toHaveBeenCalled();
|
|
});
|
|
|
|
it("should handle user:deleted event", function () {
|
|
$scope.selectedUser = { id: 1, name: "John" };
|
|
|
|
$scope.$broadcast("user:deleted", 1);
|
|
|
|
expect($scope.selectedUser).toBeNull();
|
|
});
|
|
|
|
it("should emit event when user is selected", function () {
|
|
spyOn($scope, "$emit");
|
|
var user = { id: 1, name: "John" };
|
|
|
|
UserController.selectUser(user);
|
|
|
|
expect($scope.$emit).toHaveBeenCalledWith("user:selected", user);
|
|
});
|
|
});
|
|
|
|
// ==========================================================================
|
|
// SCOPE TESTS
|
|
// ==========================================================================
|
|
|
|
describe("UserController Scope Methods", function () {
|
|
it("should expose controller methods on scope", function () {
|
|
expect($scope.loadUsers).toBeDefined();
|
|
expect($scope.selectUser).toBeDefined();
|
|
expect($scope.saveUser).toBeDefined();
|
|
expect($scope.deleteUser).toBeDefined();
|
|
});
|
|
|
|
it("should initialize scope properties", function () {
|
|
expect($scope.users).toBeDefined();
|
|
expect($scope.selectedUser).toBeDefined();
|
|
expect($scope.loading).toBeDefined();
|
|
expect($scope.error).toBeDefined();
|
|
});
|
|
});
|
|
|
|
// ==========================================================================
|
|
// EDGE CASES AND ERROR HANDLING
|
|
// ==========================================================================
|
|
|
|
describe("Error Handling", function () {
|
|
it("should handle undefined user service", function () {
|
|
expect(function () {
|
|
UserController.loadUsers();
|
|
}).not.toThrow();
|
|
});
|
|
|
|
it("should handle null response data", function () {
|
|
UserService.getUsers.and.returnValue(null);
|
|
UserController.loadUsers();
|
|
expect($scope.users).toEqual(null);
|
|
});
|
|
|
|
it("should handle empty user list", function () {
|
|
UserService.getUsers.and.returnValue([]);
|
|
UserController.loadUsers();
|
|
expect($scope.users.length).toBe(0);
|
|
});
|
|
|
|
it("should handle malformed user data", function () {
|
|
UserService.getUsers.and.returnValue([
|
|
{ id: 1 }, // Missing name
|
|
{ name: "Jane" }, // Missing id
|
|
]);
|
|
|
|
UserController.loadUsers();
|
|
expect($scope.users.length).toBe(2);
|
|
});
|
|
});
|
|
|
|
// ==========================================================================
|
|
// ASYNC OPERATIONS
|
|
// ==========================================================================
|
|
|
|
describe("Async Operations", function () {
|
|
it("should handle promise resolution", function () {
|
|
var deferred = $q.defer();
|
|
UserService.getUsers.and.returnValue(deferred.promise);
|
|
|
|
UserController.loadUsers();
|
|
var result = [{ id: 1, name: "John" }];
|
|
deferred.resolve(result);
|
|
|
|
$scope.$apply(); // Trigger digest cycle
|
|
|
|
expect($scope.users).toEqual(result);
|
|
});
|
|
|
|
it("should handle promise rejection", function () {
|
|
var deferred = $q.defer();
|
|
UserService.getUsers.and.returnValue(deferred.promise);
|
|
|
|
UserController.loadUsers();
|
|
deferred.reject("Network error");
|
|
|
|
$scope.$apply();
|
|
|
|
expect($scope.error).toBe("Network error");
|
|
});
|
|
|
|
it("should handle $timeout operations", function () {
|
|
$scope.message = "";
|
|
UserController.showMessage("Welcome!");
|
|
|
|
expect($scope.message).toBe("Welcome!");
|
|
|
|
$timeout.flush();
|
|
expect($scope.message).toBe("");
|
|
});
|
|
});
|
|
});
|
|
|
|
// ============================================================================
|
|
// JEST VERSION
|
|
// ============================================================================
|
|
|
|
describe("UserController (Jest)", () => {
|
|
let controller;
|
|
let scope;
|
|
let userService;
|
|
let authService;
|
|
|
|
beforeEach(() => {
|
|
// Mock services
|
|
userService = {
|
|
getUsers: jest.fn().mockReturnValue([]),
|
|
getUserById: jest.fn().mockReturnValue(null),
|
|
saveUser: jest.fn().mockReturnValue(true),
|
|
deleteUser: jest.fn().mockReturnValue(true),
|
|
};
|
|
|
|
authService = {
|
|
isAuthenticated: jest.fn().mockReturnValue(true),
|
|
getCurrentUser: jest
|
|
.fn()
|
|
.mockReturnValue({ id: 1, name: "Current User" }),
|
|
logout: jest.fn(),
|
|
};
|
|
|
|
// Create mock scope
|
|
scope = {
|
|
users: [],
|
|
selectedUser: null,
|
|
loading: false,
|
|
error: null,
|
|
};
|
|
|
|
// Controller logic would be extracted and tested here
|
|
controller = {
|
|
loadUsers: jest.fn(),
|
|
selectUser: jest.fn(),
|
|
saveUser: jest.fn(),
|
|
deleteUser: jest.fn(),
|
|
};
|
|
});
|
|
|
|
describe("Initialization", () => {
|
|
test("should initialize with default values", () => {
|
|
expect(controller).toBeDefined();
|
|
expect(scope.loading).toBe(false);
|
|
expect(scope.error).toBeNull();
|
|
});
|
|
|
|
test("should load users on initialization", () => {
|
|
userService.getUsers.mockReturnValue([
|
|
{ id: 1, name: "User 1" },
|
|
{ id: 2, name: "User 2" },
|
|
]);
|
|
|
|
expect(userService.getUsers).toBeDefined();
|
|
});
|
|
});
|
|
|
|
describe("Methods", () => {
|
|
test("should call loadUsers", () => {
|
|
controller.loadUsers();
|
|
expect(controller.loadUsers).toHaveBeenCalled();
|
|
});
|
|
|
|
test("should call selectUser with user data", () => {
|
|
const user = { id: 1, name: "John" };
|
|
controller.selectUser(user);
|
|
expect(controller.selectUser).toHaveBeenCalledWith(user);
|
|
});
|
|
});
|
|
|
|
describe("Error Handling", () => {
|
|
test("should handle errors gracefully", () => {
|
|
expect(() => {
|
|
controller.loadUsers();
|
|
}).not.toThrow();
|
|
});
|
|
|
|
test("should handle null responses", () => {
|
|
userService.getUsers.mockReturnValue(null);
|
|
expect(userService.getUsers()).toBeNull();
|
|
});
|
|
});
|
|
});
|