public void TestAddTheSameDriver()
        {
            UserLogInResponse res = new UserLogInResponse
            {
                api_ret_message = "success",
                api_ret_code    = 0,
                session_token   = "token2",
                status          = 200,
                timestamp       = DateTime.UtcNow,
                groups          = new List <UserGroup> {
                    new UserGroup {
                        creator_id  = "creator1",
                        description = "gdesc1",
                        group_id    = "group_id1",
                        name        = "group1"
                    }
                },
                user = new UserInfo {
                    user_id = "uid1"
                }
            };

            using (FakeCloud cloud = new FakeCloud(res))
            {
                CloudServer.request <CloudResponse>(new WebClient(), REST_COMMAND_ADD,
                                                    new Dictionary <object, object> {
                    { "email", "*****@*****.**" },
                    { "password", "12345" }
                });
            }

            Driver driver = Wammer.Model.DriverCollection.Instance.FindOne(Query.EQ("email", "*****@*****.**"));

            Assert.IsNotNull(driver);
        }
        public static void RemoveOwner(string userId)
        {
            try
            {
                Model.Driver driver = Model.DriverCollection.Instance.FindOne(Query.EQ("_id", userId));
                if (driver == null)
                {
                    throw new UserDoesNotExistException("driver " + userId + " does not exist");
                }


                CloudServer.request <CloudResponse>(
                    new WebClient(),
                    StationMgmtURL + "station/drivers/remove",
                    new Dictionary <object, object>
                {
                    { CloudServer.PARAM_API_KEY, CloudServer.APIKey },
                    { CloudServer.PARAM_SESSION_TOKEN, driver.session_token },
                    { CloudServer.PARAM_USER_ID, userId },
                }
                    );
            }
            catch (WammerCloudException e)
            {
                ExtractApiRetMsg(e);

                throw;
            }
        }
        public void TestRemoveDriver_RemoveWhenSingleItem()
        {
            mongodb.GetDatabase("wammer").GetCollection <Driver>("drivers").RemoveAll();
            mongodb.GetDatabase("wammer").GetCollection("station").RemoveAll();

            mongodb.GetDatabase("wammer").GetCollection <Driver>("drivers").Insert(
                new Driver
            {
                user_id = "exist_uid1",
                email   = "*****@*****.**",
                folder  = "resource\\user_exist_uid1",
                groups  = new List <UserGroup> {
                    new UserGroup {
                        group_id = "123"
                    }
                }
            });

            mongodb.GetDatabase("wammer").GetCollection("station").Insert(
                new StationInfo()
            {
                Id = "1234"
            });

            using (FakeCloud cloud = new FakeCloud(new CloudResponse()))
            {
                CloudServer.request <CloudResponse>(new WebClient(), "http://localhost:8080/v2/station/drivers/remove",
                                                    new Dictionary <object, object> {
                    { "session_token", "token123" },
                    { "user_ID", "exist_uid1" }
                });
                Assert.IsNull(Wammer.Model.StationCollection.Instance.FindOne());
            }
        }
        /// <summary>
        /// Update Dropbox quota for Waveface
        /// </summary>
        /// <param name="quota"></param>
        /// <exception cref="Wammer.Station.Management.DropboxNotConnectedException">
        /// Waveface has not connected to Dropbox
        /// </exception>
        /// <exception cref="Wammer.Station.Management.DropboxNotInstalledException">
        /// Dropbox is not installed
        /// </exception>
        public static void UpdateDropbox(long quota)
        {
            try
            {
                if (!DropboxHelper.IsInstalled())
                {
                    throw new DropboxNotInstalledException("Dropbox is not installed");
                }

                CloudResponse res = CloudServer.request <CloudResponse>(
                    new WebClient(),
                    StationMgmtURL + "cloudstorage/dropbox/update",
                    new Dictionary <object, object> {
                    { "quota", quota }
                },
                    true
                    );
            }
            catch (Cloud.WammerCloudException e)
            {
                ExtractApiRetMsg(e);

                throw;
            }
        }
        /// <summary>
        /// Connect Waveface to Dropbox
        /// </summary>
        /// <param name="quota"></param>
        /// <exception cref="Wammer.Station.Management.DropboxNoSyncFolderException">
        /// Dropbox sync folder does not exist
        /// </exception>
        /// <exception cref="Wammer.Station.Management.WrongAccountException">
        /// Link to inconsistent Dropbox account
        /// </exception>
        /// <exception cref="Wammer.Station.Management.DropboxNotInstalledException">
        /// Dropbox is not installed
        /// </exception>
        public static void ConnectDropbox(long quota)
        {
            try
            {
                if (!DropboxHelper.IsInstalled())
                {
                    throw new DropboxNotInstalledException("Dropbox is not installed");
                }

                string        folder = DropboxHelper.GetSyncFolder();
                CloudResponse res    = CloudServer.request <CloudResponse>(
                    new WebClient(),
                    StationMgmtURL + "cloudstorage/dropbox/connect",
                    new Dictionary <object, object> {
                    { "quota", quota }, { "folder", folder }
                },
                    true
                    );
            }
            catch (Cloud.WammerCloudException e)
            {
                ExtractApiRetMsg(e);

                throw;
            }
        }
        /// <summary>
        /// Add a user to a station
        /// </summary>
        /// <param name="email"></param>
        /// <param name="password"></param>
        /// <returns>station's session token</returns>
        /// <exception cref="Wammer.Station.Management.AuthenticationException">
        /// Invalid user name or password
        /// </exception>
        /// <exception cref="Wammer.Station.Management.StationAlreadyHasDriverException">
        /// The station already has an driver
        /// </exception>
        /// <exception cref="Wammer.Station.Management.UserAlreadyHasStationException">
        /// The user already has a station. The station's info, such as id/location/sync time, can
        /// be retrieved from the exception
        /// </exception>
        /// <exception cref="Wammer.Station.Management.StationServiceDownException">
        /// Unable to connect to station service, service down?
        /// </exception>
        /// <exception cref="Wammer.Station.Management.ConnectToCloudException">
        /// Unable to connect to waveface cloud, network down?
        /// </exception>
        public static AddUserResult AddUser(string email, string password)
        {
            try
            {
                AddUserResponse res = CloudServer.request <AddUserResponse>(
                    new WebClient(),
                    StationMgmtURL + "station/drivers/add",
                    new Dictionary <object, object> {
                    { "email", email },
                    { "password", password }
                });

                return(new AddUserResult()
                {
                    UserId = res.UserId, IsPrimaryStation = res.IsPrimaryStation
                });
            }
            catch (Cloud.WammerCloudException e)
            {
                if (e.HttpError == WebExceptionStatus.ConnectFailure)
                {
                    throw new StationServiceDownException("Station service down?");
                }

                switch (e.WammerError)
                {
                case (int)StationApiError.ConnectToCloudError:
                    throw new ConnectToCloudException(e.Message);

                case (int)StationApiError.AuthFailed:
                    throw new AuthenticationException(e.Message);

                case (int)StationApiError.DriverExist:
                    throw new StationAlreadyHasDriverException(e.Message);

                case (int)StationApiError.AlreadyHasStaion:
                    StationSignUpResponse resp = fastJSON.JSON.Instance.
                                                 ToObject <Cloud.StationSignUpResponse>(e.response);
                    throw new UserAlreadyHasStationException
                          {
                              Id           = resp.station.station_id,
                              Location     = resp.station.location,
                              LastSyncTime = resp.station.LastSeen,
                              ComputerName = resp.station.computer_name
                          };

                case 0x4000 + 4:                         // user not exist
                    throw new AuthenticationException(e.Message);

                default:
                    throw;
                }
            }
        }
        /// <summary>
        /// Disconnect Waveface from Dropbox
        /// </summary>
        public static void DisconnectDropbox()
        {
            try
            {
                CloudResponse res = CloudServer.request <CloudResponse>(
                    new WebClient(),
                    StationMgmtURL + "cloudstorage/dropbox/disconnect",
                    new Dictionary <object, object>(),
                    true
                    );
            }
            catch (Cloud.WammerCloudException e)
            {
                ExtractApiRetMsg(e);

                throw;
            }
        }
        /// <summary>
        /// Get Dropbox OAuth URL
        /// </summary>
        /// <exception cref="Wammer.Station.Management.GetDropboxOAuthException">
        /// Unable to get Dropbox OAuth information
        /// </exception>
        public static string GetDropboxOAuthUrl()
        {
            try
            {
                GetDropboxOAuthResponse res = CloudServer.request <GetDropboxOAuthResponse>(
                    new WebClient(),
                    StationMgmtURL + "cloudstorage/dropbox/oauth",
                    new Dictionary <object, object>(),
                    true
                    );
                return(res.oauth_url);
            }
            catch (Cloud.WammerCloudException e)
            {
                ExtractApiRetMsg(e);

                throw;
            }
        }
        public static void StationOffline()
        {
            try
            {
                CloudServer.request <CloudResponse>(
                    new WebClient(),
                    StationMgmtURL + "station/offline",
                    new Dictionary <object, object>
                {
                    { CloudServer.PARAM_API_KEY, CloudServer.APIKey },
                }
                    );
            }
            catch (WammerCloudException e)
            {
                ExtractApiRetMsg(e);

                throw;
            }
        }
        public static ListDriverResponse ListUser()
        {
            try
            {
                ListDriverResponse res = CloudServer.request <ListDriverResponse>(
                    new WebClient(),
                    StationMgmtURL + "station/drivers/list",
                    new Dictionary <object, object>
                {
                    { CloudServer.PARAM_API_KEY, CloudServer.APIKey },
                }
                    );

                return(res);
            }
            catch (WammerCloudException e)
            {
                ExtractApiRetMsg(e);

                throw;
            }
        }
        public static GetStatusResponse GetStationStatus()
        {
            try
            {
                GetStatusResponse res = CloudServer.request <GetStatusResponse>(
                    new WebClient(),
                    StationMgmtURL + "station/status/get",
                    new Dictionary <object, object>
                {
                    { CloudServer.PARAM_API_KEY, CloudServer.APIKey },
                }
                    );

                return(res);
            }
            catch (WammerCloudException e)
            {
                ExtractApiRetMsg(e);

                throw;
            }
        }
        public static void StationOnline(string email, string password)
        {
            try
            {
                CloudServer.request <CloudResponse>(
                    new WebClient(),
                    StationMgmtURL + "station/online",
                    new Dictionary <object, object>
                {
                    { CloudServer.PARAM_API_KEY, CloudServer.APIKey },
                    { "email", email },
                    { "password", password }
                }
                    );
            }
            catch (WammerCloudException e)
            {
                ExtractApiRetMsg(e);

                throw;
            }
        }
        public void TestAddADriver_incorrectUserNamePwd()
        {
            UserLogInResponse res1 = new UserLogInResponse
            {
                api_ret_message = "station res msg",
                api_ret_code    = 4097,              // cloud retuns 4097 for invalid user name or password
                session_token   = "token1",
                status          = (int)HttpStatusCode.Forbidden,
                timestamp       = DateTime.UtcNow,
                groups          = new List <UserGroup>(),
                user            = new UserInfo {
                    user_id = "uid1"
                }
            };

            using (FakeCloud cloud = new FakeCloud(res1, res1.status))
            {
                try
                {
                    CloudServer.request <CloudResponse>(
                        new WebClient(),
                        "http://*****:*****@gmail.com" },
                        { "password", "12345" }
                    });
                }
                catch (WammerCloudException e)
                {
                    Assert.AreEqual((int)StationApiError.AuthFailed, e.WammerError);
                    return;
                }

                Assert.Fail("Expected exception is not thrown");
            }
        }
        public void TestAddADriver()
        {
            StationSignUpResponse res1 = new StationSignUpResponse
            {
                api_ret_code    = 0,
                api_ret_message = "success",
                session_token   = "token1",
                status          = 200,
                timestamp       = DateTime.UtcNow
            };

            UserLogInResponse res2 = new UserLogInResponse
            {
                api_ret_message = "success",
                api_ret_code    = 0,
                session_token   = "token2",
                status          = 200,
                timestamp       = DateTime.UtcNow,
                groups          = new List <UserGroup> {
                    new UserGroup {
                        creator_id  = "creator1",
                        description = "gdesc1",
                        group_id    = "group_id1",
                        name        = "group1"
                    }
                },
                user = new UserInfo {
                    user_id = "uid1"
                },
                stations = new List <UserStation>()
                {
                    new UserStation()
                    {
                        station_id = "stationId", type = "primary"
                    }
                }
            };

            StationLogOnResponse res3 = new StationLogOnResponse(200, DateTime.UtcNow, "token3");

            res3.api_ret_code = 0;

            using (FakeCloud cloud = new FakeCloud(res1))
            {
                cloud.addJsonResponse(res3);
                cloud.addJsonResponse(res2);
                CloudServer.request <CloudResponse>(new WebClient(), "http://*****:*****@gmail.com" },
                    { "password", "12345" }
                });


                // verify db
                Driver driver = mongodb.GetDatabase("wammer").
                                GetCollection <Driver>("drivers").FindOne(
                    Query.EQ("email", "*****@*****.**"));

                Assert.AreEqual("*****@*****.**", driver.email);
                Assert.AreEqual(@"resource\user_uid1", driver.folder);
                Assert.AreEqual(res2.user.user_id, driver.user_id);
                Assert.IsTrue(driver.isPrimaryStation);
                Assert.AreEqual(1, driver.groups.Count);
                Assert.AreEqual(res2.session_token, driver.session_token);
                Assert.AreEqual(res2.groups[0].group_id, driver.groups[0].group_id);
                Assert.AreEqual(res2.groups[0].name, driver.groups[0].name);
                Assert.AreEqual(res2.groups[0].description, driver.groups[0].description);

                //verify station
                Wammer.Model.StationInfo s = Wammer.Model.StationCollection.Instance.FindOne();
                Assert.IsNotNull(s);
                Assert.AreEqual("token3", s.SessionToken);
            }
        }