package org.influxdb.inflow;

import com.google.gson.Gson;
import org.influxdb.InfluxDB.UserPrivilege;
import org.influxdb.dto.QueryResult;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.testng.annotations.Test;
import static org.mockito.Matchers.anyString;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeSuite;

public class AdminTest extends AbstractTest {

  @BeforeSuite()
  @Override
  public void beforeSuite() throws Exception {
    super.beforeSuite();
  }
  
  @Test
  public void testCreateUser() throws InflowException, Exception {
    Admin adminObject = this.getAdminObject();

    assertEquals(
            adminObject.createUser("test", "test", UserPrivilege.ALL),
            this.getEmptyQueryResult()
    );
  }

  @Test
  public void testChangeUserPassword() throws InflowException, Exception {
    Admin adminObject = this.getAdminObject();
    
    // expected influx query to be run to reset user password
    String expectedInfluxQuery = "SET PASSWORD FOR " + this.TEST_TARGET_USERNAME + " = '" + this.TEST_TARGET_PASSWORD + "'";

    // a successful changeUserPassword() call will return an empty result set
    // with no errors, etc
    assertEquals(
            adminObject.changeUserPassword(this.TEST_TARGET_USERNAME, this.TEST_TARGET_PASSWORD),
            this.getEmptyQueryResult()
    );
    
    // if the mock returned empty ResultSet,
    // make sure the last query run was in fact the expectedInfluxQuery to reset the password
    assertEquals(
            Client.getLastQuery(),
            expectedInfluxQuery
    );
  }

  @Test
  public void testShowUsers() throws InflowException, Exception {
    String usersResultJson = this.loadResourceFileDataAsString("/result-test-users.example.json");
    Gson gson = new Gson();
    final QueryResult usersQueryResult = gson.fromJson(usersResultJson, QueryResult.class);

    Client clientMock = this.getMockClient();

    // mock intended query result of show users when calling query()
    Mockito.when(clientMock.query(anyString(), anyString()))
            .thenAnswer(new Answer<QueryResult>() {
              @Override
              public QueryResult answer(InvocationOnMock invocation) throws Throwable {
                Object[] args = invocation.getArguments();
                if ( args[0] != null ) {
                  String databaseName = args[0].toString();
                }
                if ( args[1] != null ) {
                  Client.setLastQuery(args[1].toString());
                }
                return usersQueryResult;
              }
            });

    Admin adminMock = new Admin(clientMock);

    assertEquals(usersQueryResult, adminMock.showUsers());
  }

  private Admin getAdminObject() throws Exception {
    // make an Admin object that uses a mock client that returns empty query results
    return new Admin(this.getMockClientThatReturnsEmptyQueryResult());
  }

}

@@ -703,70 +703,729 @@
     
-assertEquals(%0A            adminObject.createUser(%22test%22, %22test
+// a successful createUser() call%0A    // CREAT USER .. WITH PASSWORD ..%0A    // will return an empty result set, if no no errors, etc%0A    assertEquals(%0A            adminObject.createUser(%22bofh234%22, %22compy567%22, UserPrivilege.ALL),%0A            this.getEmptyQueryResult()%0A    );%0A    %0A    // the default mockClient getAdminObject() uses from getMockClientThatReturnsEmptyQueryResult()%0A    // sets the last query run, so validate last query value%0A    assertEquals(%0A            Client.getLastQuery(),%0A            %22CREATE USER bofh234 WITH PASSWORD 'compy567' WITH ALL PRIVILEGES%22%0A    );%0A    %0A    // same thing but do it for bobby ro the read only analyst%0A    assertEquals(%0A            adminObject.createUser(%22bobbyro32%22, %22pomp78
 %22, U
@@ -1429,35 +1429,36 @@
 , UserPrivilege.
-ALL
+READ
 ),%0A            t
@@ -1482,32 +1482,172 @@
 Result()%0A    );%0A
+    assertEquals(%0A            Client.getLastQuery(),%0A            %22CREATE USER bobbyro32 WITH PASSWORD 'pomp78' WITH READ PRIVILEGES%22%0A    );%0A
   %7D%0A%0A  @Test%0A  p
@@ -1998,21 +1998,57 @@
 ssword()
- call
+%0A    // SET PASSWORD FOR .. = '..'%0A    //
  will re
@@ -2075,20 +2075,15 @@
  set
-%0A    // with
+, if no
  no 

update admin test comments to explain how the admin class is being tested and add a create user read only variant