/*
 * Created by IntelliJ IDEA.
 * User: Mike
 * Date: Feb 19, 2004
 * Time: 4:07:29 PM
 */
package com.atlassian.confluence.rpc.soap.services;

import com.atlassian.confluence.rpc.RemoteException;
import com.atlassian.confluence.rpc.soap.AbstractSoapTestCase;
import com.atlassian.confluence.rpc.soap.beans.RemoteUser;
import com.atlassian.confluence.security.SpacePermissionManager;
import com.atlassian.confluence.user.AuthenticatedUserThreadLocal;
import com.atlassian.confluence.user.UserAccessor;
import com.atlassian.confluence.util.LicenseTestHelper;
import com.atlassian.confluence.setup.BootstrapManager;
import com.atlassian.user.Group;
import com.atlassian.user.User;
import com.atlassian.user.search.page.PagerUtils;
import com.atlassian.license.LicenseManager;
import com.mockobjects.constraint.Constraint;
import com.mockobjects.dynamic.C;
import com.mockobjects.dynamic.Mock;

public class TestUsersSoapService extends AbstractSoapTestCase
{
    private UsersSoapService service;
    private Mock mockPermissionManager;
    private Mock mockServiceHelper;

    public void setUp() throws Exception
    {
        super.setUp();
        service = new UsersSoapService();

        // Set the current user
        AuthenticatedUserThreadLocal.setUser(user);

        // setup mock objects
        mockPermissionManager = new Mock(SpacePermissionManager.class);
        service.setSpacePermissionManager((SpacePermissionManager) mockPermissionManager.proxy());

        service.setUserAccessor(userAccessor);

        mockServiceHelper = new Mock(SoapServiceHelper.class);
        service.setSoapServiceHelper((SoapServiceHelper) mockServiceHelper.proxy());

        // Also set the license so we don't run into problems with the number of users
        LicenseTestHelper.setupLicenseRegistry();
        LicenseManager.getInstance().setLicense(LicenseTestHelper.LICENSE_EVALUATION_EXPIRED, BootstrapManager.DEFAULT_LICENSE_REGISTRY_KEY);
    }

    public void tearDown() throws Exception
    {
        super.tearDown();

        AuthenticatedUserThreadLocal.setUser(null);
    }

    private void verifyMocks()
    {
        mockPermissionManager.verify();
        mockServiceHelper.verify();
    }

    public void testGetUser() throws RemoteException
    {
        String userTwoName = "fred";

        try
        {
            service.getUser(userTwoName); // User doesn't exist
            fail("should have barfed.");
        }
        catch (RemoteException e)
        {
        }

        // Create the "fred" user
        User userTwo = userAccessor.createUser(userTwoName);

        RemoteUser  expected = new RemoteUser(userTwo);
        RemoteUser  result = service.getUser(userTwoName);
        assertEquals(expected, result);
        verifyMocks();
    }

    public void testAddUserOrGroupWithoutAdministrativePermissionFails() throws RemoteException
    {
        mockServiceHelper.expectAndThrow("assertCanAdministrate", new RemoteException());
        try
        {
            service.addUser(null, null);
            fail("should have barfed.");
        }
        catch (RemoteException e)
        {
        }

        mockServiceHelper.expectAndThrow("assertCanAdministrate", new RemoteException());
        try
        {
            service.addGroup(null);
            fail("should have barfed.");
        }
        catch (RemoteException e)
        {
        }
        verifyMocks();
    }

    public void testAddUser() throws RemoteException
    {
        RemoteUser  rUser = new RemoteUser();
        rUser.setName("fflintstone");
        rUser.setFullname("Fred Flintstone");
        rUser.setEmail("fred@flintstone.com");

        mockServiceHelper.expect("assertCanAdministrate");
        Constraint[] constaints = new Constraint[5];
        constaints[0] = C.eq("fflintstone");
        constaints[1] = C.eq("rubble");
        constaints[2] = C.eq("fred@flintstone.com");
        constaints[3] = C.eq("Fred Flintstone");
        constaints[4] = C.eq(new String[]{UserAccessor.GROUP_CONFLUENCE_USERS});

        assertTrue(service.addUser(rUser, "rubble"));
        verifyMocks();
    }

    public void testAddGroup() throws Exception
    {
        // test group doesn't exist
        mockServiceHelper.expect("assertCanAdministrate");
        assertTrue(service.addGroup("admins"));

        // test group already exists
        userAccessor.createGroup("admins");

        mockServiceHelper.expect("assertCanAdministrate");

        assertFalse(service.addGroup("admins"));
        verifyMocks();
    }

    public void testUserGroups() throws Exception
    {
        Group adminGroup = userAccessor.createGroup("admins");
        Group userGroup = userAccessor.createGroup("users");

        userAccessor.addMembership(adminGroup, user);
        userAccessor.addMembership(userGroup, user);

        mockServiceHelper.expect("assertCanAdministrate");
        String[] groups = service.getUserGroups("bob");
        assertEquals(2, groups.length);
        assertEquals("admins", groups[0]);
        assertEquals("users", groups[1]);
        verifyMocks();
    }

    public void testAddUserToNonExistantGroupFails() throws RemoteException
    {
        mockServiceHelper.expect("assertCanAdministrate");

        try
        {
            service.addUserToGroup("bob", "admins");
            fail("should have barfed.");
        }
        catch (RemoteException e)
        {
        }
        verifyMocks();
    }

    public void testAddUserToGroup() throws Exception
    {
        // Create the group
        Group adminGroup = userAccessor.createGroup("admins");

        mockServiceHelper.expect("assertCanAdministrate");

        service.addUserToGroup("bob", "admins");
        assertEquals("admins", ((Group)PagerUtils.toList(userAccessor.getGroups()).get(0)).getName());
        verifyMocks();
    }
}