def setup(self):
        """
        User being used during test: id = 5, username = test1
        """
        self.port = 8084
        handle_db_seed()
        self.app = APP
        self.app.config['SQLALCHEMY_DATABASE_URI'] = mscolab_settings.SQLALCHEMY_DB_URI
        self.app.config['MSCOLAB_DATA_DIR'] = mscolab_settings.MSCOLAB_DATA_DIR
        self.app, sockio, cm, fm = initialize_managers(self.app)
        self.fm = fm
        self.cm = cm
        db.init_app(self.app)
        self.MSCOLAB_URL_TEST = f"http://localhost:{self.port}"

        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
                                       mscolab_server_url=self.MSCOLAB_URL_TEST)
        self._login()
        self._activate_project_at_index(0)
        QtTest.QTest.mouseClick(self.window.adminWindowBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.admin_window = self.window.admin_window
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()
Exemple #2
0
    def setup(self):
        # start mscolab server
        self.app = APP
        self.app.config[
            'SQLALCHEMY_DATABASE_URI'] = mscolab_settings.SQLALCHEMY_DB_URI
        self.app.config['MSCOLAB_DATA_DIR'] = mscolab_settings.MSCOLAB_DATA_DIR
        self.app.config['UPLOAD_FOLDER'] = mscolab_settings.UPLOAD_FOLDER
        self.app, _, cm, fm = initialize_managers(self.app)
        self.fm = fm
        self.cm = cm
        db.init_app(self.app)

        logging.debug("starting")
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(
            data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
            mscolab_server_url=MSCOLAB_URL_TEST)
        self._login()
        self._activate_project_at_index(0)
        # activate project window here by clicking button
        QtTest.QTest.mouseClick(self.window.chatWindowBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.chat_window = self.window.chat_window
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()
Exemple #3
0
 def setup(self):
     self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(PORTS)
     QtTest.QTest.qWait(500)
     self.application = QtWidgets.QApplication(sys.argv)
     self.window = MSSMscolabWindow(data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
                                    mscolab_server_url=self.url)
     self.sockets = []
Exemple #4
0
 def setup(self):
     mscolab_settings.enable_basic_http_authentication = False
     self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(PORTS, mscolab_settings)
     QtTest.QTest.qWait(100)
     self.application = QtWidgets.QApplication(sys.argv)
     self.window = MSSMscolabWindow(data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
                                    mscolab_server_url=self.url)
Exemple #5
0
 def setup(self):
     handle_db_seed()
     self.port = 8084
     self.app = APP
     self.app.config[
         'SQLALCHEMY_DATABASE_URI'] = mscolab_settings.SQLALCHEMY_DB_URI
     self.app.config['MSCOLAB_DATA_DIR'] = mscolab_settings.MSCOLAB_DATA_DIR
     self.app.config['UPLOAD_FOLDER'] = mscolab_settings.UPLOAD_FOLDER
     self.app, sockio, cm, fm = initialize_managers(self.app)
     self.fm = fm
     self.cm = cm
     db.init_app(self.app)
     self.MSCOLAB_URL_TEST = f"http://localhost:{self.port}"
     logging.debug("starting")
     self.application = QtWidgets.QApplication(sys.argv)
     self.window = MSSMscolabWindow(
         data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
         mscolab_server_url=self.MSCOLAB_URL_TEST)
    def setup(self):
        handle_db_seed()
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
                                       mscolab_server_url=MSCOLAB_URL_TEST)
        self.window.show()
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()

        self.app = APP
        self.app.config['SQLALCHEMY_DATABASE_URI'] = mscolab_settings.SQLALCHEMY_DB_URI
        self.app.config['MSCOLAB_DATA_DIR'] = mscolab_settings.MSCOLAB_DATA_DIR
        self.app.config['UPLOAD_FOLDER'] = mscolab_settings.UPLOAD_FOLDER
        self.app, _, cm, fm = initialize_managers(self.app)
        self.fm = fm
        self.cm = cm
        db.init_app(self.app)
Exemple #7
0
 def setup(self):
     self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(
         PORTS)
     QtTest.QTest.qWait(100)
     self.application = QtWidgets.QApplication(sys.argv)
     self.window = MSSMscolabWindow(
         data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
         mscolab_server_url=self.url)
     self.window.show()
     self._connect_to_mscolab()
     self._login()
     self._activate_project_at_index(0)
     # activate project window here by clicking button
     QtTest.QTest.mouseClick(self.window.chatWindowBtn,
                             QtCore.Qt.LeftButton)
     QtWidgets.QApplication.processEvents()
     self.chat_window = self.window.chat_window
     QtTest.QTest.qWaitForWindowExposed(self.window)
     QtWidgets.QApplication.processEvents()
Exemple #8
0
 def setup(self):
     self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(
         PORTS)
     QtTest.QTest.qWait(100)
     self.application = QtWidgets.QApplication(sys.argv)
     self.window = MSSMscolabWindow(
         data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
         mscolab_server_url=self.url)
     with self.app.app_context():
         self.user = User.query.filter_by(id=8).first()
Exemple #9
0
 def setup(self):
     self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(
         PORTS)
     QtTest.QTest.qWait(500)
     self.application = QtWidgets.QApplication(sys.argv)
     self.window = MSSMscolabWindow(
         data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
         mscolab_server_url=self.url)
     self.sockets = []
     self.fm = file_manager.FileManager(mscolab_settings.MSCOLAB_DATA_DIR)
     self._example_data()
     self.cleanup_pid = set()
     data = {'email': 'a', 'password': '******'}
     r = requests.post(self.url + '/token', data=data)
     self.token = json.loads(r.text)['token']
     with self.app.app_context():
         self.user = User.query.filter_by(id=8).first()
 def setup(self):
     self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(
         PORTS)
     QtTest.QTest.qWait(100)
     self.application = QtWidgets.QApplication(sys.argv)
     self.window = MSSMscolabWindow(
         data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
         mscolab_server_url=self.url)
     self.sockets = []
     self.file_message_counter = [0] * 2
     self.undefined_p_id = 123
     self.no_perm_p_id = 2
     data = {'email': 'a', 'password': '******'}
     r = requests.post(self.url + '/token', data=data)
     self.token = json.loads(r.text)['token']
     with self.app.app_context():
         self.user = User.query.filter_by(id=8).first()
Exemple #11
0
    def setup(self):
        self.process, self.url, self.app, self.sio, self.cm, self.fm = mscolab_start_server(
            PORTS)
        QtTest.QTest.qWait(500)
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(
            data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
            mscolab_server_url=self.url)

        with self.app.app_context():
            response = mscolab_register_and_login(self.app, self.url,
                                                  'a1a@a1a', 'a1a', 'a1a')
            _ = mscolab_create_project(self.app,
                                       self.url,
                                       response,
                                       path='f3',
                                       description='f3 test example')
            self.user = User.query.filter_by(emailid="a1a@a1a").first()
            self.test_p_id = get_recent_pid(self.fm, self.user)
            self.test_sid = 25
            socket_storage = {'s_id': self.test_sid, 'u_id': self.user.id}
            self.sockets = [socket_storage]
Exemple #12
0
    def setup(self):
        self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(
            PORTS)
        QtTest.QTest.qWait(500)
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(
            data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
            mscolab_server_url=self.url)
        self.cm = ChatManager()
        self.room_name = "europe"
        data = {'email': 'a', 'password': '******'}
        r = requests.post(self.url + '/token', data=data)
        self.token = json.loads(r.text)['token']
        with self.app.app_context():
            self.user = User.query.filter_by(id=8).first()

        data = {
            "token": self.token,
            "path": self.room_name,
            "description": "test description"
        }
        url = url_join(self.url, 'create_project')
        requests.post(url, data=data)
Exemple #13
0
class Test_MscolabProject(object):
    def setup(self):
        self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(
            PORTS)
        QtTest.QTest.qWait(100)
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(
            data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
            mscolab_server_url=self.url)
        self.window.show()
        self._connect_to_mscolab()
        self._login()
        self._activate_project_at_index(0)
        # activate project window here by clicking button
        QtTest.QTest.mouseClick(self.window.chatWindowBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.chat_window = self.window.chat_window
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()

    def teardown(self):
        if self.window.chat_window:
            self.window.chat_window.hide()
        if self.window.conn:
            self.window.conn.disconnect()
        self.window.hide()
        QtWidgets.QApplication.processEvents()
        self.application.quit()
        QtWidgets.QApplication.processEvents()
        self.process.terminate()

    def test_send_message(self):
        self._send_message("**test message**")
        self._send_message("**test message**")
        with self.app.app_context():
            assert Message.query.filter_by(
                text='**test message**').count() == 2

    def test_search_message(self):
        self._send_message("**test message**")
        self._send_message("**test message**")
        message_index = self.chat_window.messageList.count() - 1
        self.window.chat_window.searchMessageLineEdit.setText("test message")
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseClick(self.window.chat_window.searchPrevBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.chat_window.messageList.item(
            message_index).isSelected() is True
        QtTest.QTest.mouseClick(self.window.chat_window.searchPrevBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.chat_window.messageList.item(message_index -
                                                 1).isSelected() is True
        QtTest.QTest.mouseClick(self.window.chat_window.searchNextBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.chat_window.messageList.item(
            message_index).isSelected() is True

    def test_copy_message(self):
        self._send_message("**test message**")
        self._send_message("**test message**")
        self._activate_context_menu_action(Actions.COPY)
        assert Qt.QApplication.clipboard().text() == "**test message**"

    def test_reply_message(self):
        self._send_message("**test message**")
        self._send_message("**test message**")
        parent_message_id = self._get_message_id(
            self.chat_window.messageList.count() - 1)
        self._activate_context_menu_action(Actions.REPLY)
        self.chat_window.messageText.setPlainText('test reply')
        QtTest.QTest.mouseClick(self.chat_window.sendMessageBtn,
                                QtCore.Qt.LeftButton)
        QtTest.QTest.qWait(100)
        with self.app.app_context():
            message = Message.query.filter_by(text='test reply')
            assert message.count() == 1
            assert message.first().reply_id == parent_message_id

    def test_edit_message(self):
        self._send_message("**test message**")
        self._send_message("**test message**")
        self._activate_context_menu_action(Actions.EDIT)
        self.chat_window.messageText.setPlainText('test edit')
        QtTest.QTest.mouseClick(self.chat_window.editMessageBtn,
                                QtCore.Qt.LeftButton)
        QtTest.QTest.qWait(100)
        with self.app.app_context():
            assert Message.query.filter_by(text='test edit').count() == 1

    def test_delete_message(self):
        self._send_message("**test message**")
        self._send_message("**test message**")
        self._activate_context_menu_action(Actions.DELETE)
        QtTest.QTest.qWait(100)
        with self.app.app_context():
            assert Message.query.filter_by(text='test edit').count() == 0

    def _connect_to_mscolab(self):
        self.window.url.setEditText(self.url)
        QtTest.QTest.mouseClick(self.window.toggleConnectionBtn,
                                QtCore.Qt.LeftButton)
        QtTest.QTest.qWait(500)

    def _login(self):
        # login
        self.window.emailid.setText('a')
        self.window.password.setText('a')
        QtTest.QTest.mouseClick(self.window.loginButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

    def _activate_project_at_index(self, index):
        item = self.window.listProjects.item(index)
        point = self.window.listProjects.visualItemRect(item).center()
        QtTest.QTest.mouseClick(self.window.listProjects.viewport(),
                                QtCore.Qt.LeftButton,
                                pos=point)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseDClick(self.window.listProjects.viewport(),
                                 QtCore.Qt.LeftButton,
                                 pos=point)
        QtWidgets.QApplication.processEvents()

    def _activate_context_menu_action(self, action_index):
        item = self.chat_window.messageList.item(
            self.chat_window.messageList.count() - 1)
        message_widget = self.chat_window.messageList.itemWidget(item)
        message_widget.context_menu.actions()[action_index].trigger()

    def _send_message(self, text):
        self.chat_window.messageText.setPlainText(text)
        QtTest.QTest.mouseClick(self.chat_window.sendMessageBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(500)

    def _get_message_id(self, index):
        item = self.chat_window.messageList.item(index)
        message_widget = self.chat_window.messageList.itemWidget(item)
        return message_widget.id
Exemple #14
0
class Test_Chat(object):
    def setup(self):
        self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(
            PORTS)
        QtTest.QTest.qWait(100)
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(
            data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
            mscolab_server_url=self.url)
        self.sockets = []

    def teardown(self):
        for socket in self.sockets:
            socket.disconnect()
        if self.window.version_window:
            self.window.version_window.close()
        if self.window.conn:
            self.window.conn.disconnect()
        self.window.hide()
        QtWidgets.QApplication.processEvents()
        self.application.quit()
        QtWidgets.QApplication.processEvents()
        self.process.terminate()

    def test_send_message(self):
        response = self._login()
        sio = socketio.Client()
        self.sockets.append(sio)
        messages = []

        def handle_incoming_message(msg):
            msg = json.loads(msg)
            messages.append(msg)

        sio.on('chat-message-client', handler=handle_incoming_message)
        sio.connect(self.url)
        sio.emit('start', response)
        sio.sleep(2)
        sio.emit(
            "chat-message", {
                "p_id": 1,
                "token": response['token'],
                "message_text": "message from 1",
                "reply_id": -1
            })
        sio.sleep(2)
        # testing non-ascii message
        sio.emit(
            "chat-message", {
                "p_id": 1,
                "token": response['token'],
                "message_text": "® non ascii",
                "reply_id": -1
            })
        sio.sleep(2)
        assert messages[0]["text"] == "message from 1"
        assert messages[1]["text"] == "® non ascii"
        with self.app.app_context():
            message = Message.query.filter_by(text="message from 1").first()
            assert message.p_id == 1
            assert message.u_id == 8

            message = Message.query.filter_by(text="® non ascii").first()
            assert message is not None

    def test_get_messages(self):
        response = self._login()
        sio = socketio.Client()
        self.sockets.append(sio)
        sio.connect(self.url)
        sio.emit('start', response)
        sio.sleep(2)
        sio.emit(
            "chat-message", {
                "p_id": 1,
                "token": response['token'],
                "message_text": "message from 1",
                "reply_id": -1
            })
        sio.emit(
            "chat-message", {
                "p_id": 1,
                "token": response['token'],
                "message_text": "message from 1",
                "reply_id": -1
            })
        sio.sleep(2)
        with self.app.app_context():
            messages = self.cm.get_messages(1)
            assert messages[0]["text"] == "message from 1"
            assert len(messages) == 2
            assert messages[0]["u_id"] == 8
            timestamp = datetime.datetime(1970, 1,
                                          1).strftime("%Y-%m-%d, %H:%M:%S")
            messages = self.cm.get_messages(1, timestamp)
            assert len(messages) == 2
            assert messages[0]["u_id"] == 8
            timestamp = datetime.datetime.now().strftime("%Y-%m-%d, %H:%M:%S")
            messages = self.cm.get_messages(1, timestamp)
            assert len(messages) == 0

    def test_get_messages_api(self):
        response = self._login()
        sio = socketio.Client()
        self.sockets.append(sio)
        sio.connect(self.url)
        sio.emit('start', response)
        sio.sleep(2)
        sio.emit(
            "chat-message", {
                "p_id": 1,
                "token": response['token'],
                "message_text": "message from 1",
                "reply_id": -1
            })
        sio.emit(
            "chat-message", {
                "p_id": 1,
                "token": response['token'],
                "message_text": "message from 1",
                "reply_id": -1
            })
        sio.sleep(2)

        token = response["token"]
        data = {
            "token":
            token,
            "p_id":
            1,
            "timestamp":
            datetime.datetime(1970, 1, 1).strftime("%Y-%m-%d, %H:%M:%S")
        }
        # returns an array of messages
        url = url_join(self.url, 'messages')
        res = requests.get(url, data=data).json()
        assert len(res["messages"]) == 2

        data["token"] = "dummy"
        # returns False due to bad authorization
        r = requests.get(url, data=data)
        assert r.text == "False"

    def test_edit_message(self):
        response = self._login()
        sio = socketio.Client()
        self.sockets.append(sio)
        edited_messages = []

        def handle_message_edited(msg):
            msg = json.loads(msg)
            edited_messages.append(msg)

        sio.on('edit-message-client', handler=handle_message_edited)
        sio.connect(self.url)
        sio.emit('start', response)
        sio.sleep(2)
        sio.emit(
            "chat-message", {
                "p_id": 1,
                "token": response['token'],
                "message_text": "Edit this message",
                "reply_id": -1
            })
        sio.sleep(2)
        with self.app.app_context():
            message = Message.query.filter_by(text="Edit this message").first()
        sio.emit(
            'edit-message', {
                "message_id": message.id,
                "new_message_text": "I have updated the message",
                "p_id": message.p_id,
                "token": response["token"]
            })
        sio.sleep(2)
        assert len(edited_messages) == 1
        assert edited_messages[0][
            "new_message_text"] == "I have updated the message"

    def test_delete_message(self):
        response = self._login()
        sio = socketio.Client()
        self.sockets.append(sio)
        deleted_messages = []

        def handle_message_deleted(msg):
            msg = json.loads(msg)
            deleted_messages.append(msg)

        sio.on('delete-message-client', handler=handle_message_deleted)
        sio.connect(self.url)
        sio.emit('start', response)
        sio.sleep(2)
        sio.emit(
            "chat-message", {
                "p_id": 1,
                "token": response['token'],
                "message_text": "delete this message",
                "reply_id": -1
            })
        sio.sleep(2)
        with self.app.app_context():
            message = Message.query.filter_by(
                text="delete this message").first()
        sio.emit('delete-message', {
            'message_id': message.id,
            'p_id': 1,
            'token': response["token"]
        })
        sio.sleep(2)
        assert len(deleted_messages) == 1
        assert deleted_messages[0]["message_id"] == message.id
        with self.app.app_context():
            assert Message.query.filter_by(
                text="delete this message").count() == 0

    def test_upload_file(self):
        response = self._login()
        token = response["token"]
        sio = socketio.Client()
        self.sockets.append(sio)
        message_recv = []

        def handle_incoming_message(msg):
            msg = json.loads(msg)
            message_recv.append(msg)

        sio.on('chat-message-client', handler=handle_incoming_message)
        sio.connect(self.url)
        sio.emit('start', response)
        sio.sleep(1)
        files = {'file': open(icons('16x16'), 'rb')}
        data = {
            "token": token,
            "p_id": 1,
            "message_type": int(MessageType.IMAGE)
        }
        url = url_join(self.url, 'message_attachment')
        requests.post(url, data=data, files=files)
        sio.sleep(1)
        assert len(message_recv) == 1
        assert fs.path.join("uploads", "1",
                            "mss-logo") in message_recv[0]["text"]

    def _login(self):
        url = url_join(self.url, 'token')
        r = requests.post(url, data={'email': 'a', 'password': '******'})
        response = json.loads(r.text)
        return response
Exemple #15
0
class Test_Mscolab(object):
    sample_path = os.path.join(os.path.dirname(__file__), "..", "..", "..", "docs", "samples", "flight-tracks")

    def setup(self):
        self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(PORTS)
        QtTest.QTest.qWait(500)
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
                                       mscolab_server_url=self.url)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()

    def teardown(self):
        if self.window.version_window:
            self.window.version_window.close()
        if self.window.conn:
            self.window.conn.disconnect()
        self.window.force_close_view_windows()
        self.window.close_external_windows()
        self.application.quit()
        QtWidgets.QApplication.processEvents()
        self.process.terminate()

    def test_url_combo(self):
        assert self.window.url.count() >= 1

    @mock.patch("PyQt5.QtWidgets.QMessageBox")
    def test_login(self, mockbox):
        self._connect_to_mscolab()
        self._login()
        # screen shows logout button
        assert self.window.label.text() == 'Welcome, a'
        assert self.window.loginWidget.isVisible() is False
        # test project listing visibility
        assert self.window.listProjects.model().rowCount() == 3
        # test logout
        QtTest.QTest.mouseClick(self.window.logoutButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.listProjects.model().rowCount() == 0
        # ToDo understand why this is not cleared
        # assert self.window.label.text() == ""
        assert self.window.conn is None

        for exc in [requests.exceptions.ConnectionError, requests.exceptions.InvalidSchema,
                    requests.exceptions.InvalidURL, requests.exceptions.SSLError, Exception("")]:
            with mock.patch("requests.get", new=ExceptionMock(exc).raise_exc):
                self.window.connect_handler()
        assert mockbox.critical.call_count == 5

    def test_disconnect(self):
        self._connect_to_mscolab()
        QtTest.QTest.mouseClick(self.window.toggleConnectionBtn, QtCore.Qt.LeftButton)
        assert self.window.mscolab_server_url is None

    def test_activate_project(self):
        self._connect_to_mscolab()
        self._login()
        # activate a project
        self._activate_project_at_index(0)
        assert self.window.active_pid is not None

    @mock.patch("PyQt5.QtWidgets.QMessageBox")
    def test_view_open(self, mockbox):
        self._connect_to_mscolab()
        self._login()
        # test without activating project
        QtTest.QTest.mouseClick(self.window.topview, QtCore.Qt.LeftButton)
        QtTest.QTest.mouseClick(self.window.sideview, QtCore.Qt.LeftButton)
        QtTest.QTest.mouseClick(self.window.tableview, QtCore.Qt.LeftButton)
        QtTest.QTest.mouseClick(self.window.linearview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 0
        # test after activating project
        self._activate_project_at_index(0)
        QtTest.QTest.mouseClick(self.window.tableview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 1
        QtTest.QTest.mouseClick(self.window.topview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 2
        QtTest.QTest.mouseClick(self.window.sideview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 3
        QtTest.QTest.mouseClick(self.window.linearview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 4
        QtTest.QTest.mouseClick(self.window.topview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 4

        project = self.window.active_pid
        uid = self.window.user["id"]
        topview = self.window.active_windows[1]
        tableview = self.window.active_windows[0]
        self.window.handle_update_permission(project, uid, "viewer")
        assert not tableview.btAddWayPointToFlightTrack.isEnabled()
        assert any(action.text() == "Ins WP" and not action.isEnabled() for action in topview.mpl.navbar.actions())
        self.window.handle_update_permission(project, uid, "creator")
        assert tableview.btAddWayPointToFlightTrack.isEnabled()
        assert any(action.text() == "Ins WP" and action.isEnabled() for action in topview.mpl.navbar.actions())

    @mock.patch("PyQt5.QtWidgets.QFileDialog.getSaveFileName",
                return_value=(fs.path.join(mscolab_settings.MSCOLAB_DATA_DIR, 'test_export.ftml'), None))
    def test_handle_export(self, mockbox):
        self._connect_to_mscolab()
        self._login()
        self._activate_project_at_index(0)
        QtTest.QTest.mouseClick(self.window.exportBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        exported_waypoints = WaypointsTableModel(filename=fs.path.join(self.window.data_dir, 'test_export.ftml'))
        wp_count = len(self.window.waypoints_model.waypoints)
        assert wp_count == 2
        for i in range(wp_count):
            assert exported_waypoints.waypoint_data(i).lat == self.window.waypoints_model.waypoint_data(i).lat

    @pytest.mark.parametrize("ext", [".ftml", ".txt"])
    @mock.patch("PyQt5.QtWidgets.QMessageBox")
    def test_import_file(self, mockbox, ext):
        with mock.patch("mslib.msui.mscolab.config_loader",
                        return_value={"Text": ["txt", "mslib.plugins.io.text", "save_to_txt"]}):
            self.window.export_plugins = self.window.add_plugins()
        with mock.patch("mslib.msui.mscolab.config_loader",
                        return_value={"Text": ["txt", "mslib.plugins.io.text", "load_from_txt"]}):
            self.window.import_plugins = self.window.add_plugins()
        with mock.patch("PyQt5.QtWidgets.QFileDialog.getSaveFileName", return_value=(fs.path.join(
                mscolab_settings.MSCOLAB_DATA_DIR, f'test_import{ext}'), None)):
            with mock.patch("PyQt5.QtWidgets.QFileDialog.getOpenFileName", return_value=(fs.path.join(
                    mscolab_settings.MSCOLAB_DATA_DIR, f'test_import{ext}'), None)):
                self._connect_to_mscolab()
                self._login()
                self._activate_project_at_index(0)
                exported_wp = WaypointsTableModel(waypoints=self.window.waypoints_model.waypoints)
                QtTest.QTest.mouseClick(self.window.exportBtn, QtCore.Qt.LeftButton)
                QtWidgets.QApplication.processEvents()
                self.window.waypoints_model.invert_direction()
                QtWidgets.QApplication.processEvents()
                QtTest.QTest.qWait(100)
                assert exported_wp.waypoint_data(0).lat != self.window.waypoints_model.waypoint_data(0).lat
                QtTest.QTest.mouseClick(self.window.importBtn, QtCore.Qt.LeftButton)
                QtWidgets.QApplication.processEvents()
                QtTest.QTest.qWait(100)
                assert len(self.window.waypoints_model.waypoints) == 2
                imported_wp = self.window.waypoints_model
                wp_count = len(imported_wp.waypoints)
                assert wp_count == 2
                for i in range(wp_count):
                    assert exported_wp.waypoint_data(i).lat == imported_wp.waypoint_data(i).lat

    def test_work_locally_toggle(self):
        self._connect_to_mscolab()
        self._login()
        self._activate_project_at_index(0)
        self.window.workLocallyCheckBox.setChecked(True)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(100)
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(100)
        wpdata_local = self.window.waypoints_model.waypoint_data(0)
        self.window.workLocallyCheckBox.setChecked(False)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(100)
        wpdata_server = self.window.waypoints_model.waypoint_data(0)
        assert wpdata_local.lat != wpdata_server.lat

    @mock.patch("PyQt5.QtWidgets.QMessageBox.question", return_value=QtWidgets.QMessageBox.Yes)
    def test_user_delete(self, mockmessage):
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        u_id = self.window.user['id']
        QtTest.QTest.mouseClick(self.window.deleteAccountButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.listProjects) == 0
        assert self.window.loggedInWidget.isVisible() is False
        with self.app.app_context():
            assert User.query.filter_by(emailid='something').count() == 0
            assert Permission.query.filter_by(u_id=u_id).count() == 0

    @mock.patch("mslib.msui.mscolab.QtWidgets.QErrorMessage.showMessage")
    @mock.patch("mslib.msui.mscolab.get_open_filename", return_value=os.path.join(sample_path, u"example.ftml"))
    def test_set_exported_file(self, mockopen, mockmessage):
        # name is misleading
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.listProjects.model().rowCount() == 0
        QtTest.QTest.mouseClick(self.window.addProject, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.path.setText(str("example"))
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.description.setText(str("example"))
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseClick(self.window.add_proj_dialog.browse, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        okWidget = self.window.add_proj_dialog.buttonBox.button(self.window.add_proj_dialog.buttonBox.Ok)
        QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.listProjects.model().rowCount() == 1

    @mock.patch("PyQt5.QtWidgets.QErrorMessage")
    def test_add_project(self, mockbox):
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.label.text() == 'Welcome, something'
        assert self.window.loginWidget.isVisible() is False
        self._create_project("Alpha", "Description Alpha")
        assert mockbox.return_value.showMessage.call_count == 2
        with mock.patch("PyQt5.QtWidgets.QLineEdit.text", return_value=None):
            self._create_project("Alpha2", "Description Alpha")
        with mock.patch("PyQt5.QtWidgets.QTextEdit.toPlainText", return_value=None):
            self._create_project("Alpha3", "Description Alpha")
        self._create_project("/", "Description Alpha")
        assert mockbox.return_value.showMessage.call_count == 5
        assert self.window.listProjects.model().rowCount() == 1
        self._create_project("reproduce-test", "Description Test")
        assert self.window.listProjects.model().rowCount() == 2
        self._activate_project_at_index(0)
        assert self.window.active_project_name == "Alpha"
        self._activate_project_at_index(1)
        assert self.window.active_project_name == "reproduce-test"

    @mock.patch("mslib.msui.mscolab.MSCOLAB_AuthenticationDialog.exec_", return_value=QtWidgets.QDialog.Accepted)
    @mock.patch("PyQt5.QtWidgets.QErrorMessage")
    def test_failed_authorize(self, mockbox, mockauth):
        class response:
            def __init__(self, code, text):
                self.status_code = code
                self.text = text

        self._connect_to_mscolab()
        with mock.patch("requests.Session.post", new=ExceptionMock(requests.exceptions.ConnectionError).raise_exc):
            self._login()
        with mock.patch("requests.Session.post", return_value=response(201, "False")):
            self._login()
        with mock.patch("requests.Session.post", return_value=response(401, "False")):
            self._login()

        # No return after self.error_dialog.showMessage('Oh no, server authentication were incorrect.')
        # causes 4 instead of 3 messages, I am not sure if this is on purpose.
        assert mockbox.return_value.showMessage.call_count == 4

    def test_add_user(self):
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        # screen shows logout button
        assert self.window.label.text() == 'Welcome, something'
        assert self.window.loginWidget.isVisible() is False

    def test_close_help_dialog(self):
        QtTest.QTest.mouseClick(self.window.helpBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.close()
        assert self.window.help_dialog is None

    def test_open_help_dialog(self):
        QtTest.QTest.mouseClick(self.window.helpBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.help_dialog is not None
        self.window.close()

    @mock.patch("mslib.msui.mscolab.QtWidgets.QInputDialog.getText", return_value=("flight7", True))
    def test_handle_delete_project(self, mocktext):
        # pytest.skip('needs a review for the delete button pressed. Seems to delete a None project')
        self._connect_to_mscolab()
        self._create_user("berta", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.label.text() == 'Welcome, berta'
        assert self.window.loginWidget.isVisible() is False
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight7", "Description flight7")
        assert self.window.active_pid is None
        self._activate_project_at_index(0)
        p_id = self.window.get_recent_pid()
        assert p_id is not None
        assert self.window.listProjects.model().rowCount() == 1
        QtTest.QTest.mouseClick(self.window.deleteProjectBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        p_id = self.window.get_recent_pid()
        assert p_id is None

    def test_get_recent_pid(self):
        self._connect_to_mscolab()
        self._create_user("anton", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.label.text() == 'Welcome, anton'
        assert self.window.loginWidget.isVisible() is False
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight2", "Description flight2")
        current_pid = self.window.get_recent_pid()
        self._create_project("flight3", "Description flight3")
        self._create_project("flight4", "Description flight4")
        # ToDo fix number after cleanup initial data
        assert self.window.get_recent_pid() == current_pid + 2

    def test_get_recent_project(self):
        self._connect_to_mscolab()
        self._create_user("berta", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.label.text() == 'Welcome, berta'
        assert self.window.loginWidget.isVisible() is False
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight1234", "Description flight1234")
        self._activate_project_at_index(0)
        project = self.window.get_recent_project()
        assert project["path"] == "flight1234"
        assert project["access_level"] == "creator"

    def test_delete_project_from_list(self):
        self._connect_to_mscolab()
        self._create_user("other", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.label.text() == 'Welcome, other'
        assert self.window.loginWidget.isVisible() is False
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight3", "Description flight3")
        self._activate_project_at_index(0)
        p_id = self.window.get_recent_pid()
        self.window.delete_project_from_list(p_id)
        assert self.window.active_pid is None

    @mock.patch("PyQt5.QtWidgets.QMessageBox")
    @mock.patch("sys.exit")
    def test_create_dir_exceptions(self, mockexit, mockbox):
        with mock.patch("fs.open_fs", new=ExceptionMock(fs.errors.CreateFailed).raise_exc):
            self.window.data_dir = "://"
            self.window.create_dir()
            assert mockbox.critical.call_count == 1
            assert mockexit.call_count == 1

        with mock.patch("fs.open_fs", new=ExceptionMock(fs.opener.errors.UnsupportedProtocol).raise_exc):
            self.window.data_dir = "://"
            self.window.create_dir()
            assert mockbox.critical.call_count == 2
            assert mockexit.call_count == 2

    def _connect_to_mscolab(self):
        self.window.url.setEditText(self.url)
        QtTest.QTest.mouseClick(self.window.toggleConnectionBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(500)

    def _login(self, emailid="a", password="******"):
        self.window.emailid.setText(emailid)
        self.window.password.setText(password)
        QtTest.QTest.mouseClick(self.window.loginButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(500)

    @mock.patch("mslib.msui.mscolab.QtWidgets.QErrorMessage.showMessage")
    def _create_user(self, username, email, password, mockbox):
        QtTest.QTest.mouseClick(self.window.addUser, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.username.setText(str(username))
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.emailid.setText(str(email))
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.password.setText(str(password))
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.rePassword.setText(str(password))
        QtWidgets.QApplication.processEvents()
        okWidget = self.window.add_user_dialog.buttonBox.button(self.window.add_user_dialog.buttonBox.Ok)
        QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        # ToDo get rid of that QMessageBox

    @mock.patch("mslib.msui.mscolab.QtWidgets.QErrorMessage.showMessage")
    def _create_project(self, path, description, mockbox):
        QtTest.QTest.mouseClick(self.window.addProject, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.path.setText(str(path))
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.description.setText(str(description))
        QtWidgets.QApplication.processEvents()
        okWidget = self.window.add_proj_dialog.buttonBox.button(self.window.add_proj_dialog.buttonBox.Ok)
        QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

    def _activate_project_at_index(self, index):
        item = self.window.listProjects.item(index)
        point = self.window.listProjects.visualItemRect(item).center()
        QtTest.QTest.mouseClick(self.window.listProjects.viewport(), QtCore.Qt.LeftButton, pos=point)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseDClick(self.window.listProjects.viewport(), QtCore.Qt.LeftButton, pos=point)
        QtWidgets.QApplication.processEvents()
Exemple #16
0
class Test_MscolabProject(object):
    def setup(self):
        # start mscolab server
        self.app = APP
        self.app.config[
            'SQLALCHEMY_DATABASE_URI'] = mscolab_settings.SQLALCHEMY_DB_URI
        self.app.config['MSCOLAB_DATA_DIR'] = mscolab_settings.MSCOLAB_DATA_DIR
        self.app.config['UPLOAD_FOLDER'] = mscolab_settings.UPLOAD_FOLDER
        self.app, _, cm, fm = initialize_managers(self.app)
        self.fm = fm
        self.cm = cm
        db.init_app(self.app)

        logging.debug("starting")
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(
            data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
            mscolab_server_url=MSCOLAB_URL_TEST)
        self._login()
        self._activate_project_at_index(0)
        # activate project window here by clicking button
        QtTest.QTest.mouseClick(self.window.chatWindowBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.chat_window = self.window.chat_window
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()

    def teardown(self):
        # to disconnect connections, and clear token
        # Not logging out since it pops up a dialog
        # self.window.logout()
        if self.window.chat_window:
            self.window.chat_window.hide()
        if self.window.conn:
            self.window.conn.disconnect()
        self.window.hide()
        QtWidgets.QApplication.processEvents()
        self.application.quit()
        QtWidgets.QApplication.processEvents()

    def test_send_message(self):
        self._send_message("**test message**")
        self._send_message("**test message**")
        # wait till server processes the change
        time.sleep(1)
        with self.app.app_context():
            assert Message.query.filter_by(
                text='**test message**').count() == 2

    def test_search_message(self):
        message_index = self.chat_window.messageList.count() - 1
        self.chat_window.searchMessageLineEdit.setText("test message")
        QtTest.QTest.mouseClick(self.chat_window.searchPrevBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.chat_window.messageList.item(
            message_index).isSelected() is True
        QtTest.QTest.mouseClick(self.chat_window.searchPrevBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.chat_window.messageList.item(message_index -
                                                 1).isSelected() is True
        QtTest.QTest.mouseClick(self.chat_window.searchNextBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.chat_window.messageList.item(
            message_index).isSelected() is True

    def test_copy_message(self):
        self._activate_context_menu_action(Actions.COPY)
        assert Qt.QApplication.clipboard().text() == "**test message**"

    def test_reply_message(self):
        parent_message_id = self._get_message_id(
            self.chat_window.messageList.count() - 1)
        self._activate_context_menu_action(Actions.REPLY)
        self.chat_window.messageText.setPlainText('test reply')
        QtTest.QTest.mouseClick(self.chat_window.sendMessageBtn,
                                QtCore.Qt.LeftButton)
        time.sleep(1)
        with self.app.app_context():
            message = Message.query.filter_by(text='test reply')
            assert message.count() == 1
            assert message.first().reply_id == parent_message_id

    def test_edit_message(self):
        self._activate_context_menu_action(Actions.EDIT)
        self.chat_window.messageText.setPlainText('test edit')
        QtTest.QTest.mouseClick(self.chat_window.editMessageBtn,
                                QtCore.Qt.LeftButton)
        time.sleep(1)
        with self.app.app_context():
            assert Message.query.filter_by(text='test edit').count() == 1

    def test_delete_message(self):
        self._activate_context_menu_action(Actions.DELETE)
        time.sleep(1)
        with self.app.app_context():
            assert Message.query.filter_by(text='test edit').count() == 0

    def _connect_to_mscolab(self):
        self.window.url.setEditText("http://localhost:8084")
        QtTest.QTest.mouseClick(self.window.connectMscolab,
                                QtCore.Qt.LeftButton)
        time.sleep(0.5)

    def _login(self):
        # login
        self._connect_to_mscolab()
        self.window.emailid.setText('a')
        self.window.password.setText('a')
        QtTest.QTest.mouseClick(self.window.loginButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

    def _activate_project_at_index(self, index):
        item = self.window.listProjects.item(index)
        point = self.window.listProjects.visualItemRect(item).center()
        QtTest.QTest.mouseClick(self.window.listProjects.viewport(),
                                QtCore.Qt.LeftButton,
                                pos=point)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseDClick(self.window.listProjects.viewport(),
                                 QtCore.Qt.LeftButton,
                                 pos=point)
        QtWidgets.QApplication.processEvents()

    def _activate_context_menu_action(self, action_index):
        item = self.chat_window.messageList.item(
            self.chat_window.messageList.count() - 1)
        message_widget = self.chat_window.messageList.itemWidget(item)
        message_widget.context_menu.actions()[action_index].trigger()

    def _send_message(self, text):
        self.chat_window.messageText.setPlainText(text)
        QtTest.QTest.mouseClick(self.chat_window.sendMessageBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

    def _get_message_id(self, index):
        item = self.chat_window.messageList.item(index)
        message_widget = self.chat_window.messageList.itemWidget(item)
        return message_widget.id
class Test_MscolabAdminWindow(object):
    def setup(self):
        """
        User being used during test: id = 5, username = test1
        """
        self.port = 8084
        handle_db_seed()
        self.app = APP
        self.app.config['SQLALCHEMY_DATABASE_URI'] = mscolab_settings.SQLALCHEMY_DB_URI
        self.app.config['MSCOLAB_DATA_DIR'] = mscolab_settings.MSCOLAB_DATA_DIR
        self.app, sockio, cm, fm = initialize_managers(self.app)
        self.fm = fm
        self.cm = cm
        db.init_app(self.app)
        self.MSCOLAB_URL_TEST = f"http://localhost:{self.port}"

        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
                                       mscolab_server_url=self.MSCOLAB_URL_TEST)
        self._login()
        self._activate_project_at_index(0)
        QtTest.QTest.mouseClick(self.window.adminWindowBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.admin_window = self.window.admin_window
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()

    def teardown(self):
        # to disconnect connections, and clear token
        # Not logging out since it pops up a dialog
        # self.window.logout()
        if self.window.admin_window:
            self.window.admin_window.close()
        if self.window.conn:
            self.window.conn.disconnect()
        self.window.close()
        QtWidgets.QApplication.processEvents()
        self.application.quit()
        QtWidgets.QApplication.processEvents()

    def test_permission_filter(self):
        len_added_users = self.admin_window.modifyUsersTable.rowCount()
        # Change filter to viewer
        self.admin_window.modifyUsersPermissionFilter.currentTextChanged.emit("viewer")
        QtWidgets.QApplication.processEvents()
        # Check how many users are visible
        visible_row_count = self._get_visible_row_count(self.admin_window.modifyUsersTable)
        assert visible_row_count == 1
        # Change it back to all
        self.admin_window.modifyUsersPermissionFilter.currentTextChanged.emit("all")
        QtWidgets.QApplication.processEvents()
        # Check how many rows are visible
        visible_row_count = self._get_visible_row_count(self.admin_window.modifyUsersTable)
        assert visible_row_count == len_added_users

    def test_text_search_filter(self):
        len_unadded_users = self.admin_window.addUsersTable.rowCount()
        len_added_users = self.admin_window.modifyUsersTable.rowCount()
        # Text Search in add users Table
        QtTest.QTest.keyClicks(self.admin_window.addUsersSearch, "test2")
        QtWidgets.QApplication.processEvents()
        visible_row_count = self._get_visible_row_count(self.admin_window.addUsersTable)
        assert visible_row_count == 1
        self.admin_window.addUsersSearch.setText("")
        QtTest.QTest.keyClicks(self.admin_window.addUsersSearch, "")
        QtWidgets.QApplication.processEvents()
        visible_row_count = self._get_visible_row_count(self.admin_window.addUsersTable)
        assert visible_row_count == len_unadded_users
        # Text Search in modify users Table
        QtTest.QTest.keyClicks(self.admin_window.modifyUsersSearch, "test4")
        QtWidgets.QApplication.processEvents()
        visible_row_count = self._get_visible_row_count(self.admin_window.modifyUsersTable)
        assert visible_row_count == 1
        self.admin_window.modifyUsersSearch.setText("")
        QtTest.QTest.keyClicks(self.admin_window.modifyUsersSearch, "")
        QtWidgets.QApplication.processEvents()
        visible_row_count = self._get_visible_row_count(self.admin_window.modifyUsersTable)
        assert visible_row_count == len_added_users

    def test_permission_and_text_together(self):
        QtTest.QTest.keyClicks(self.admin_window.modifyUsersSearch, "test4")
        self.admin_window.modifyUsersPermissionFilter.currentTextChanged.emit("viewer")
        QtWidgets.QApplication.processEvents()
        visible_row_count = self._get_visible_row_count(self.admin_window.modifyUsersTable)
        assert visible_row_count == 1
        self.admin_window.modifyUsersPermissionFilter.currentTextChanged.emit("admin")
        QtWidgets.QApplication.processEvents()
        visible_row_count = self._get_visible_row_count(self.admin_window.modifyUsersTable)
        assert visible_row_count == 0

    def test_add_permissions(self):
        len_unadded_users = self.admin_window.addUsersTable.rowCount()
        len_added_users = self.admin_window.modifyUsersTable.rowCount()
        users = ["test2", "test3"]
        # Select users in the add users table
        self._select_users(self.admin_window.addUsersTable, users)
        QtTest.QTest.mouseClick(self.admin_window.addUsersBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        # Check if they have been added in the modify users table
        self._check_users_present(self.admin_window.modifyUsersTable, users, "admin")
        assert len_unadded_users - 2 == self.admin_window.addUsersTable.rowCount()
        assert len_added_users + 2 == self.admin_window.modifyUsersTable.rowCount()

    def test_modify_permissions(self):
        self._connect_to_mscolab()
        self._login()
        self._activate_project_at_index(0)
        users = ["test2", "test3"]
        # Select users in the add users table
        self._select_users(self.admin_window.addUsersTable, users)
        QtTest.QTest.mouseClick(self.admin_window.addUsersBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        # Select users in the modify users table
        self._select_users(self.admin_window.modifyUsersTable, users)
        # Update their permission to viewer
        index = self.admin_window.modifyUsersPermission.findText("viewer", QtCore.Qt.MatchFixedString)
        self.admin_window.modifyUsersPermission.setCurrentIndex(index)
        QtTest.QTest.mouseClick(self.admin_window.modifyUsersBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        # Check if the permission has been updated
        self._check_users_present(self.admin_window.modifyUsersTable, users, "viewer")

    def test_delete_permissions(self):
        self._connect_to_mscolab()
        self._login()
        self._activate_project_at_index(0)
        # Select users in the add users table
        users = ["test2", "test3"]
        self._select_users(self.admin_window.addUsersTable, users)
        QtTest.QTest.mouseClick(self.admin_window.addUsersBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        len_unadded_users = self.admin_window.addUsersTable.rowCount()
        len_added_users = self.admin_window.modifyUsersTable.rowCount()

        # Select users in the modify users table
        self._select_users(self.admin_window.modifyUsersTable, users)
        # Click on delete permissions
        QtTest.QTest.mouseClick(self.admin_window.deleteUsersBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        # Check if the deleted users can be found in the add users table
        self._check_users_present(self.admin_window.addUsersTable, users)
        assert len_unadded_users + 2 == self.admin_window.addUsersTable.rowCount()
        assert len_added_users - 2 == self.admin_window.modifyUsersTable.rowCount()

    def test_import_permissions(self):
        self._connect_to_mscolab()
        self._login()
        self._activate_project_at_index(0)
        index = self.admin_window.importPermissionsCB.findText("three", QtCore.Qt.MatchFixedString)
        self.admin_window.importPermissionsCB.setCurrentIndex(index)
        QtTest.QTest.mouseClick(self.admin_window.importPermissionsBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        time.sleep(1)
        assert self.admin_window.modifyUsersTable.rowCount() == 5

    def _connect_to_mscolab(self):
        self.window.url.setEditText(self.MSCOLAB_URL_TEST)
        QtTest.QTest.mouseClick(self.window.connectMscolab, QtCore.Qt.LeftButton)
        time.sleep(0.5)

    def _login(self):
        # login
        self._connect_to_mscolab()
        self.window.emailid.setText('test1')
        self.window.password.setText('test1')
        QtTest.QTest.mouseClick(self.window.loginButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

    def _activate_project_at_index(self, index):
        item = self.window.listProjects.item(index)
        point = self.window.listProjects.visualItemRect(item).center()
        QtTest.QTest.mouseClick(self.window.listProjects.viewport(), QtCore.Qt.LeftButton, pos=point)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseDClick(self.window.listProjects.viewport(), QtCore.Qt.LeftButton, pos=point)
        QtWidgets.QApplication.processEvents()

    def _select_users(self, table, users):
        for row_num in range(table.rowCount()):
            item = table.item(row_num, 0)
            username = item.text()
            if username in users:
                point = table.visualItemRect(item).center()
                QtTest.QTest.mouseClick(table.viewport(), QtCore.Qt.LeftButton, pos=point)
                QtWidgets.QApplication.processEvents()
        assert len(table.selectionModel().selectedRows()) == 2

    def _get_visible_row_count(self, table):
        visible_row_count = 0
        for row_num in range(table.rowCount()):
            if table.isRowHidden(row_num) is False:
                visible_row_count += 1
        return visible_row_count

    def _check_users_present(self, table, users, access_level=None):
        found = 0
        for row_num in range(table.rowCount()):
            item = table.item(row_num, 0)
            username = item.text()
            if username in users:
                found += 1
                if access_level is not None:
                    assert table.item(row_num, 2).text() == access_level
        assert found == 2
Exemple #18
0
class Test_Mscolab(object):
    sample_path = os.path.join(os.path.dirname(__file__), "..", "..", "..",
                               "docs", "samples", "flight-tracks")

    def setup(self):
        logging.debug("starting")
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(
            data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
            mscolab_server_url=MSCOLAB_URL_TEST)
        self.window.show()
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()

        self.app = APP
        self.app.config[
            'SQLALCHEMY_DATABASE_URI'] = mscolab_settings.SQLALCHEMY_DB_URI
        self.app.config['MSCOLAB_DATA_DIR'] = mscolab_settings.MSCOLAB_DATA_DIR
        self.app.config['UPLOAD_FOLDER'] = mscolab_settings.UPLOAD_FOLDER
        self.app, _, cm, fm = initialize_managers(self.app)
        self.fm = fm
        self.cm = cm
        db.init_app(self.app)

    def teardown(self):
        with self.app.app_context():
            email = [
                ("*****@*****.**", "something"),
                ("*****@*****.**", "other"),
                ("*****@*****.**", "anton"),
                ("*****@*****.**", "berta"),
            ]
            for em, username in email:
                mscolab_delete_all_projects(self.app, MSCOLAB_URL_TEST, em,
                                            "something", username)
                mscolab_delete_user(self.app, MSCOLAB_URL_TEST, em,
                                    "something")

        # to disconnect connections, and clear token
        self.window.disconnect_handler()
        QtWidgets.QApplication.processEvents()
        self.window.close()
        QtWidgets.QApplication.processEvents()
        self.application.quit()
        QtWidgets.QApplication.processEvents()
        with fs.open_fs(mscolab_settings.MSCOLAB_DATA_DIR) as mss_dir:
            if mss_dir.exists('local_mscolab_data'):
                mss_dir.removetree('local_mscolab_data')

    def test_url_combo(self):
        assert self.window.url.count() >= 1

    def test_login(self):
        self._login()
        # screen shows logout button
        assert self.window.loggedInWidget.isVisible() is True
        assert self.window.loginWidget.isVisible() is False
        # test project listing visibility
        assert self.window.listProjects.model().rowCount() == 1
        # test logout
        QtTest.QTest.mouseClick(self.window.logoutButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.loggedInWidget.isVisible() is False
        assert self.window.loginWidget.isVisible() is True

    def test_disconnect(self):
        self._connect_to_mscolab()
        QtTest.QTest.mouseClick(self.window.disconnectMscolab,
                                QtCore.Qt.LeftButton)
        assert self.window.mscolab_server_url is None

    def test_activate_project(self):
        self._login()
        # activate a project
        self._activate_project_at_index(0)
        assert self.window.active_pid is not None

    def test_view_open(self):
        self._login()
        # test without activating project
        QtTest.QTest.mouseClick(self.window.topview, QtCore.Qt.LeftButton)
        QtTest.QTest.mouseClick(self.window.sideview, QtCore.Qt.LeftButton)
        QtTest.QTest.mouseClick(self.window.tableview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 0
        # test after activating project
        self._activate_project_at_index(0)
        QtTest.QTest.mouseClick(self.window.tableview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 1
        QtTest.QTest.mouseClick(self.window.topview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 2
        QtTest.QTest.mouseClick(self.window.sideview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 3

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QFileDialog.getSaveFileName",
                return_value=(fs.path.join(mscolab_settings.MSCOLAB_DATA_DIR,
                                           'test_export.ftml'), None))
    def test_handle_export(self, mockbox):
        self._login()
        self._activate_project_at_index(0)
        QtTest.QTest.mouseClick(self.window.exportBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        exported_waypoints = WaypointsTableModel(
            filename=fs.path.join(self.window.data_dir, 'test_export.ftml'))
        wp_count = len(self.window.waypoints_model.waypoints)
        assert wp_count == 2
        for i in range(wp_count):
            assert exported_waypoints.waypoint_data(
                i).lat == self.window.waypoints_model.waypoint_data(i).lat

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QFileDialog.getSaveFileName",
                return_value=(fs.path.join(mscolab_settings.MSCOLAB_DATA_DIR,
                                           'test_import.ftml'), None))
    @mock.patch("mslib.msui.mss_qt.QtWidgets.QFileDialog.getOpenFileName",
                return_value=(fs.path.join(mscolab_settings.MSCOLAB_DATA_DIR,
                                           'test_import.ftml'), None))
    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_import_file(self, mockExport, mockImport, mockMessage):
        self._login()
        self._activate_project_at_index(0)
        exported_wp = WaypointsTableModel(
            waypoints=self.window.waypoints_model.waypoints)
        QtTest.QTest.mouseClick(self.window.exportBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        assert exported_wp.waypoint_data(
            0).lat != self.window.waypoints_model.waypoint_data(0).lat
        QtTest.QTest.mouseClick(self.window.importBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        assert len(self.window.waypoints_model.waypoints) == 2
        imported_wp = self.window.waypoints_model
        wp_count = len(imported_wp.waypoints)
        assert wp_count == 2
        for i in range(wp_count):
            assert exported_wp.waypoint_data(
                i).lat == imported_wp.waypoint_data(i).lat

    def test_work_locally_toggle(self):
        self._login()
        self._activate_project_at_index(0)
        self.window.workLocallyCheckBox.setChecked(True)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        wpdata_local = self.window.waypoints_model.waypoint_data(0)
        self.window.workLocallyCheckBox.setChecked(False)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        wpdata_server = self.window.waypoints_model.waypoint_data(0)
        assert wpdata_local.lat != wpdata_server.lat

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox.question",
                return_value=QtWidgets.QMessageBox.Yes)
    def test_user_delete(self, mockmessage):
        self._login()
        QtTest.QTest.mouseClick(self.window.deleteAccountButton,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.listProjects) == 0
        assert self.window.loggedInWidget.isVisible() is False
        assert self.window.loginWidget.isVisible() is True
        with self.app.app_context():
            assert User.query.filter_by(emailid='mscolab_user').count() == 0
            assert Permission.query.filter_by(u_id=16).count() == 0

    def test_add_project_handler(self):
        pass

    def test_check_an_enable_project_accept(self):
        pass

    @mock.patch("mslib.msui.mscolab.QtWidgets.QErrorMessage.showMessage")
    @mock.patch("mslib.msui.mscolab.get_open_filename",
                return_value=os.path.join(sample_path, u"example.ftml"))
    def test_set_exported_file(self, mockopen, mockmessage):
        # name is misleading
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.listProjects.model().rowCount() == 0
        QtTest.QTest.mouseClick(self.window.addProject, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.path.setText(str("example"))
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.description.setText(str("example"))
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseClick(self.window.add_proj_dialog.browse,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        okWidget = self.window.add_proj_dialog.buttonBox.button(
            self.window.add_proj_dialog.buttonBox.Ok)
        QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.listProjects.model().rowCount() == 1

    def test_add_project(self):
        # ToDo testneeds to be independent from test_user_delete
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.loggedInWidget.isVisible() is True
        self._create_project("Alpha", "Description Alpha")
        assert self.window.listProjects.model().rowCount() == 1

    def test_add_user_handler(self):
        pass

    def test_add_user(self):
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        # screen shows logout button
        assert self.window.loggedInWidget.isVisible() is True
        assert self.window.loginWidget.isVisible() is False

    def test_close_help_dialog(self):
        QtTest.QTest.mouseClick(self.window.helpBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.close()
        assert self.window.help_dialog is None

    def test_open_help_dialog(self):
        QtTest.QTest.mouseClick(self.window.helpBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.help_dialog is not None

    @mock.patch("mslib.msui.mscolab.QtWidgets.QInputDialog.getText",
                return_value=("flight7", True))
    def test_handle_delete_project(self, mocktext):
        pytest.skip("test has still a problem")
        self._connect_to_mscolab()
        self._create_user("berta", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.loggedInWidget.isVisible() is True
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight7", "Description flight7")
        self._activate_project_at_index(0)
        assert self.window.listProjects.model().rowCount() == 1

        QtTest.QTest.mouseClick(self.window.deleteProjectBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.active_pid is None
        assert self.window.listProjects.model().rowCount() == 0

    def test_close_chat_window(self):
        pass

    def test_open_admin_window(self):
        pass

    def test_authorize(self):
        pass

    def test_get_recent_pid(self):
        self._connect_to_mscolab()
        self._create_user("anton", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.loggedInWidget.isVisible() is True
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight2", "Description flight2")
        # ToDo fix number after cleanup initial data
        assert self.window.get_recent_pid() == 8

    def test_get_recent_project(self):
        self._connect_to_mscolab()
        self._create_user("berta", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.loggedInWidget.isVisible() is True
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight1234", "Description flight1234")
        self._activate_project_at_index(0)
        project = self.window.get_recent_project()
        assert project["path"] == "flight1234"
        assert project["access_level"] == "creator"

    def test_disable_navbar_action_buttons(self):
        pass

    def test_enable_navbar_action_buttons(self):
        pass

    def test_save_wp_mscolab(self):
        pass

    def test_reload_view_windows(self):
        pass

    def test_wp_mscolab(self):
        pass

    def test_handle_update_permissions(self):
        pass

    def test_delete_project_from_list(self):
        self._connect_to_mscolab()
        self._create_user("other", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.loggedInWidget.isVisible() is True
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight3", "Description flight3")
        self._activate_project_at_index(0)
        p_id = self.window.get_recent_pid()
        self.window.delete_project_from_list(p_id)
        assert self.window.active_pid is None

    def test_handle_revoke_permissions(self):
        pass

    def test_render_new_permissions(self):
        pass

    def test_handle_project_deleted(self):
        pass

    def test_handle_view(self):
        pass

    def test_setIdentifier(self):
        pass

    def _connect_to_mscolab(self):
        self.window.url.setEditText("http://*****:*****@mock.patch("mslib.msui.mscolab.QtWidgets.QErrorMessage.showMessage")
    def _create_user(self, username, email, password, mockbox):
        QtTest.QTest.mouseClick(self.window.addUser, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.username.setText(str(username))
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.emailid.setText(str(email))
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.password.setText(str(password))
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.rePassword.setText(str(password))
        QtWidgets.QApplication.processEvents()
        okWidget = self.window.add_user_dialog.buttonBox.button(
            self.window.add_user_dialog.buttonBox.Ok)
        QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        # ToDo get rid of that QMessageBox

    @mock.patch("mslib.msui.mscolab.QtWidgets.QErrorMessage.showMessage")
    def _create_project(self, path, description, mockbox):
        QtTest.QTest.mouseClick(self.window.addProject, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.path.setText(str(path))
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.description.setText(str(description))
        QtWidgets.QApplication.processEvents()
        okWidget = self.window.add_proj_dialog.buttonBox.button(
            self.window.add_proj_dialog.buttonBox.Ok)
        QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

    def _activate_project_at_index(self, index):
        item = self.window.listProjects.item(index)
        point = self.window.listProjects.visualItemRect(item).center()
        QtTest.QTest.mouseClick(self.window.listProjects.viewport(),
                                QtCore.Qt.LeftButton,
                                pos=point)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseDClick(self.window.listProjects.viewport(),
                                 QtCore.Qt.LeftButton,
                                 pos=point)
        QtWidgets.QApplication.processEvents()
Exemple #19
0
class Test_MscolabVersionHistory(object):
    def setup(self):
        self.app = APP
        self.app.config[
            'SQLALCHEMY_DATABASE_URI'] = mscolab_settings.SQLALCHEMY_DB_URI
        self.app.config['MSCOLAB_DATA_DIR'] = mscolab_settings.MSCOLAB_DATA_DIR
        self.app, _, cm, fm = initialize_managers(self.app)
        self.fm = fm
        self.cm = cm
        db.init_app(self.app)
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(
            data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
            mscolab_server_url=MSCOLAB_URL_TEST)
        self._login()
        self._activate_project_at_index(0)
        time.sleep(4)
        # activate project window here by clicking button
        QtTest.QTest.mouseClick(self.window.versionHistoryBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.version_window = self.window.version_window
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()

    def teardown(self):
        # to disconnect connections, and clear token
        # Not logging out since it pops up a dialog
        # self.window.logout()
        if self.window.version_window:
            self.window.version_window.close()
        if self.window.conn:
            self.window.conn.disconnect()
        self.window.hide()
        QtWidgets.QApplication.processEvents()
        self.application.quit()
        QtWidgets.QApplication.processEvents()

    def test_changes(self):
        self._change_version_filter(1)
        len_prev = self.version_window.changes.count()
        # make a changes
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        time.sleep(4)
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        time.sleep(4)
        self.version_window.load_all_changes()
        QtWidgets.QApplication.processEvents()
        len_after = self.version_window.changes.count()
        assert len_prev == (len_after - 2)

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QInputDialog.getText",
                return_value=["MyVersionName", True])
    def test_set_version_name(self, mockbox):
        self._change_version_filter(1)
        self._activate_change_at_index(0)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseClick(self.version_window.nameVersionBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        time.sleep(4)
        assert self.version_window.changes.currentItem(
        ).version_name == "MyVersionName"

    def test_version_name_filter(self):
        assert self.version_window.changes.count() == 1

    def test_version_name_delete(self):
        self._activate_change_at_index(0)
        QtTest.QTest.mouseClick(self.version_window.deleteVersionNameBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        time.sleep(4)
        assert self.version_window.changes.count() == 0

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox.question",
                return_value=QtWidgets.QMessageBox.Yes)
    def test_undo(self, mockbox):
        self._change_version_filter(1)
        changes_count = self.version_window.changes.count()
        self._activate_change_at_index(1)
        QtTest.QTest.mouseClick(self.version_window.checkoutBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        time.sleep(4)
        new_changes_count = self.version_window.changes.count()
        assert changes_count + 1 == new_changes_count

    def test_refresh(self):
        self._change_version_filter(1)
        changes_count = self.version_window.changes.count()
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        time.sleep(4)
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        time.sleep(4)
        QtTest.QTest.mouseClick(self.version_window.refreshBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        time.sleep(4)
        new_changes_count = self.version_window.changes.count()
        assert new_changes_count == changes_count + 2

    def _connect_to_mscolab(self):
        self.window.url.setEditText("http://localhost:8084")
        QtTest.QTest.mouseClick(self.window.connectMscolab,
                                QtCore.Qt.LeftButton)
        time.sleep(1)

    def _login(self):
        self._connect_to_mscolab()
        self.window.emailid.setText('a')
        self.window.password.setText('a')
        QtTest.QTest.mouseClick(self.window.loginButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

    def _activate_project_at_index(self, index):
        item = self.window.listProjects.item(index)
        point = self.window.listProjects.visualItemRect(item).center()
        QtTest.QTest.mouseClick(self.window.listProjects.viewport(),
                                QtCore.Qt.LeftButton,
                                pos=point)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseDClick(self.window.listProjects.viewport(),
                                 QtCore.Qt.LeftButton,
                                 pos=point)
        QtWidgets.QApplication.processEvents()

    def _activate_change_at_index(self, index):
        item = self.version_window.changes.item(index)
        point = self.version_window.changes.visualItemRect(item).center()
        QtTest.QTest.mouseClick(self.version_window.changes.viewport(),
                                QtCore.Qt.LeftButton,
                                pos=point)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.keyClick(self.version_window.changes.viewport(),
                              QtCore.Qt.Key_Return)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)

    def _change_version_filter(self, index):
        self.version_window.versionFilterCB.setCurrentIndex(index)
        self.version_window.versionFilterCB.currentIndexChanged.emit(index)
        QtWidgets.QApplication.processEvents()
        time.sleep(4)
Exemple #20
0
class Test_Mscolab(object):
    sample_path = os.path.join(os.path.dirname(__file__), "..", "..", "..",
                               "docs", "samples", "flight-tracks")

    def setup(self):
        self.process, self.url, self.app, _, self.cm, self.fm = mscolab_start_server(
            PORTS)
        QtTest.QTest.qWait(100)
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(
            data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
            mscolab_server_url=self.url)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()

    def teardown(self):
        if self.window.version_window:
            self.window.version_window.close()
        if self.window.conn:
            self.window.conn.disconnect()
        self.application.quit()
        QtWidgets.QApplication.processEvents()
        self.process.terminate()

    def test_url_combo(self):
        assert self.window.url.count() >= 1

    def test_login(self):
        self._connect_to_mscolab()
        self._login()
        # screen shows logout button
        assert self.window.label.text() == 'Welcome, a'
        assert self.window.loginWidget.isVisible() is False
        # test project listing visibility
        assert self.window.listProjects.model().rowCount() == 3
        # test logout
        QtTest.QTest.mouseClick(self.window.logoutButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.listProjects.model().rowCount() == 0
        # ToDo understand why this is not cleared
        # assert self.window.label.text() == ""
        assert self.window.conn is None

    def test_disconnect(self):
        self._connect_to_mscolab()
        QtTest.QTest.mouseClick(self.window.toggleConnectionBtn,
                                QtCore.Qt.LeftButton)
        assert self.window.mscolab_server_url is None

    def test_activate_project(self):
        self._connect_to_mscolab()
        self._login()
        # activate a project
        self._activate_project_at_index(0)
        assert self.window.active_pid is not None

    def test_view_open(self):
        self._connect_to_mscolab()
        self._login()
        # test without activating project
        QtTest.QTest.mouseClick(self.window.topview, QtCore.Qt.LeftButton)
        QtTest.QTest.mouseClick(self.window.sideview, QtCore.Qt.LeftButton)
        QtTest.QTest.mouseClick(self.window.tableview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 0
        # test after activating project
        self._activate_project_at_index(0)
        QtTest.QTest.mouseClick(self.window.tableview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 1
        QtTest.QTest.mouseClick(self.window.topview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 2
        QtTest.QTest.mouseClick(self.window.sideview, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.active_windows) == 3

    @mock.patch("PyQt5.QtWidgets.QFileDialog.getSaveFileName",
                return_value=(fs.path.join(mscolab_settings.MSCOLAB_DATA_DIR,
                                           'test_export.ftml'), None))
    def test_handle_export(self, mockbox):
        self._connect_to_mscolab()
        self._login()
        self._activate_project_at_index(0)
        QtTest.QTest.mouseClick(self.window.exportBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        exported_waypoints = WaypointsTableModel(
            filename=fs.path.join(self.window.data_dir, 'test_export.ftml'))
        wp_count = len(self.window.waypoints_model.waypoints)
        assert wp_count == 2
        for i in range(wp_count):
            assert exported_waypoints.waypoint_data(
                i).lat == self.window.waypoints_model.waypoint_data(i).lat

    @mock.patch("PyQt5.QtWidgets.QFileDialog.getSaveFileName",
                return_value=(fs.path.join(mscolab_settings.MSCOLAB_DATA_DIR,
                                           'test_import.ftml'), None))
    @mock.patch("PyQt5.QtWidgets.QFileDialog.getOpenFileName",
                return_value=(fs.path.join(mscolab_settings.MSCOLAB_DATA_DIR,
                                           'test_import.ftml'), None))
    @mock.patch("PyQt5.QtWidgets.QMessageBox")
    def test_import_file(self, mockExport, mockImport, mockMessage):
        pytest.skip("See issue #861")
        self._connect_to_mscolab()
        self._login()
        self._activate_project_at_index(0)
        exported_wp = WaypointsTableModel(
            waypoints=self.window.waypoints_model.waypoints)
        QtTest.QTest.mouseClick(self.window.exportBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(100)
        assert exported_wp.waypoint_data(
            0).lat != self.window.waypoints_model.waypoint_data(0).lat
        QtTest.QTest.mouseClick(self.window.importBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(100)
        assert len(self.window.waypoints_model.waypoints) == 2
        imported_wp = self.window.waypoints_model
        wp_count = len(imported_wp.waypoints)
        assert wp_count == 2
        for i in range(wp_count):
            assert exported_wp.waypoint_data(
                i).lat == imported_wp.waypoint_data(i).lat

    def test_work_locally_toggle(self):
        self._connect_to_mscolab()
        self._login()
        self._activate_project_at_index(0)
        self.window.workLocallyCheckBox.setChecked(True)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(100)
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(100)
        wpdata_local = self.window.waypoints_model.waypoint_data(0)
        self.window.workLocallyCheckBox.setChecked(False)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWait(100)
        wpdata_server = self.window.waypoints_model.waypoint_data(0)
        assert wpdata_local.lat != wpdata_server.lat

    @mock.patch("PyQt5.QtWidgets.QMessageBox.question",
                return_value=QtWidgets.QMessageBox.Yes)
    def test_user_delete(self, mockmessage):
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        u_id = self.window.user['id']
        QtTest.QTest.mouseClick(self.window.deleteAccountButton,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert len(self.window.listProjects) == 0
        assert self.window.loggedInWidget.isVisible() is False
        with self.app.app_context():
            assert User.query.filter_by(emailid='something').count() == 0
            assert Permission.query.filter_by(u_id=u_id).count() == 0

    @mock.patch("mslib.msui.mscolab.QtWidgets.QErrorMessage.showMessage")
    @mock.patch("mslib.msui.mscolab.get_open_filename",
                return_value=os.path.join(sample_path, u"example.ftml"))
    def test_set_exported_file(self, mockopen, mockmessage):
        # name is misleading
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.listProjects.model().rowCount() == 0
        QtTest.QTest.mouseClick(self.window.addProject, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.path.setText(str("example"))
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.description.setText(str("example"))
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseClick(self.window.add_proj_dialog.browse,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        okWidget = self.window.add_proj_dialog.buttonBox.button(
            self.window.add_proj_dialog.buttonBox.Ok)
        QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.listProjects.model().rowCount() == 1

    def test_add_project(self):
        # ToDo test needs to be independent from test_user_delete
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.label.text() == 'Welcome, something'
        assert self.window.loginWidget.isVisible() is False
        self._create_project("Alpha", "Description Alpha")
        assert self.window.listProjects.model().rowCount() == 1

    def test_add_user(self):
        self._connect_to_mscolab()
        self._create_user("something", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        # screen shows logout button
        assert self.window.label.text() == 'Welcome, something'
        assert self.window.loginWidget.isVisible() is False

    def test_close_help_dialog(self):
        QtTest.QTest.mouseClick(self.window.helpBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.close()
        assert self.window.help_dialog is None

    def test_open_help_dialog(self):
        QtTest.QTest.mouseClick(self.window.helpBtn, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.help_dialog is not None
        self.window.close()

    @mock.patch("mslib.msui.mscolab.QtWidgets.QInputDialog.getText",
                return_value=("flight7", True))
    def test_handle_delete_project(self, mocktext):
        pytest.skip(
            'needs a review for the delete button pressed. Seems to delete a None project'
        )
        self._connect_to_mscolab()
        self._create_user("berta", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.label.text() == 'Welcome, berta'
        assert self.window.loginWidget.isVisible() is False
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight7", "Description flight7")
        self._activate_project_at_index(0)
        assert self.window.listProjects.model().rowCount() == 1
        QtTest.QTest.mouseClick(self.window.deleteProjectBtn,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.listProjects.model().rowCount() == 0
        assert self.window.active_pid is None

    def test_get_recent_pid(self):
        self._connect_to_mscolab()
        self._create_user("anton", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.label.text() == 'Welcome, anton'
        assert self.window.loginWidget.isVisible() is False
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight2", "Description flight2")
        current_pid = self.window.get_recent_pid()
        self._create_project("flight3", "Description flight3")
        self._create_project("flight4", "Description flight4")
        # ToDo fix number after cleanup initial data
        assert self.window.get_recent_pid() == current_pid + 2

    def test_get_recent_project(self):
        self._connect_to_mscolab()
        self._create_user("berta", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.label.text() == 'Welcome, berta'
        assert self.window.loginWidget.isVisible() is False
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight1234", "Description flight1234")
        self._activate_project_at_index(0)
        project = self.window.get_recent_project()
        assert project["path"] == "flight1234"
        assert project["access_level"] == "creator"

    def test_delete_project_from_list(self):
        pytest.skip('needs a review for xdist')
        self._connect_to_mscolab()
        self._create_user("other", "*****@*****.**", "something")
        self._login("*****@*****.**", "something")
        assert self.window.label.text() == 'Welcome, other'
        assert self.window.loginWidget.isVisible() is False
        assert self.window.listProjects.model().rowCount() == 0
        self._create_project("flight3", "Description flight3")
        self._activate_project_at_index(0)
        p_id = self.window.get_recent_pid()
        self.window.delete_project_from_list(p_id)
        assert self.window.active_pid is None

    def _connect_to_mscolab(self):
        self.window.url.setEditText(self.url)
        QtTest.QTest.mouseClick(self.window.toggleConnectionBtn,
                                QtCore.Qt.LeftButton)
        QtTest.QTest.qWait(100)

    def _login(self, emailid="a", password="******"):
        self.window.emailid.setText(emailid)
        self.window.password.setText(password)
        QtTest.QTest.mouseClick(self.window.loginButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

    @mock.patch("mslib.msui.mscolab.QtWidgets.QErrorMessage.showMessage")
    def _create_user(self, username, email, password, mockbox):
        QtTest.QTest.mouseClick(self.window.addUser, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.username.setText(str(username))
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.emailid.setText(str(email))
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.password.setText(str(password))
        QtWidgets.QApplication.processEvents()
        self.window.add_user_dialog.rePassword.setText(str(password))
        QtWidgets.QApplication.processEvents()
        okWidget = self.window.add_user_dialog.buttonBox.button(
            self.window.add_user_dialog.buttonBox.Ok)
        QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        # ToDo get rid of that QMessageBox

    @mock.patch("mslib.msui.mscolab.QtWidgets.QErrorMessage.showMessage")
    def _create_project(self, path, description, mockbox):
        QtTest.QTest.mouseClick(self.window.addProject, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.path.setText(str(path))
        QtWidgets.QApplication.processEvents()
        self.window.add_proj_dialog.description.setText(str(description))
        QtWidgets.QApplication.processEvents()
        okWidget = self.window.add_proj_dialog.buttonBox.button(
            self.window.add_proj_dialog.buttonBox.Ok)
        QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

    def _activate_project_at_index(self, index):
        item = self.window.listProjects.item(index)
        point = self.window.listProjects.visualItemRect(item).center()
        QtTest.QTest.mouseClick(self.window.listProjects.viewport(),
                                QtCore.Qt.LeftButton,
                                pos=point)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseDClick(self.window.listProjects.viewport(),
                                 QtCore.Qt.LeftButton,
                                 pos=point)
        QtWidgets.QApplication.processEvents()
class Test_Mscolab(object):
    def setup(self):

        self.application = QtWidgets.QApplication(sys.argv)
        self.window = MSSMscolabWindow(
            data_dir=mscolab_settings.MSCOLAB_DATA_DIR,
            mscolab_server_url=MSCOLAB_URL_TEST)
        self.window.show()
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()

        self.app = APP
        self.app.config[
            'SQLALCHEMY_DATABASE_URI'] = mscolab_settings.SQLALCHEMY_DB_URI
        self.app.config['MSCOLAB_DATA_DIR'] = mscolab_settings.MSCOLAB_DATA_DIR
        self.app.config['UPLOAD_FOLDER'] = mscolab_settings.UPLOAD_FOLDER
        self.app, _, cm, fm = initialize_managers(self.app)
        self.fm = fm
        self.cm = cm
        db.init_app(self.app)

    def teardown(self):
        # to disconnect connections, and clear token
        self.window.disconnect_handler()
        QtWidgets.QApplication.processEvents()
        self.window.close()
        QtWidgets.QApplication.processEvents()
        with fs.open_fs(mscolab_settings.MSCOLAB_DATA_DIR) as mss_dir:
            if mss_dir.exists('local_mscolab_data'):
                mss_dir.removetree('local_mscolab_data')
        # self.application.quit()
        # QtWidgets.QApplication.processEvents()

    @pytest.mark.skip(reason="Need to fix test for dialog")
    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_save_overwrite_to_server(self, mockbox):
        self._login()
        self._activate_project_at_index(0)
        wp_server_before = self.window.waypoints_model.waypoint_data(0)
        self.window.workLocallyCheckBox.setChecked(True)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        wp_local = self.window.waypoints_model.waypoint_data(0)
        assert wp_local.lat == wp_server_before.lat
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        wp_local_before = self.window.waypoints_model.waypoint_data(0)
        assert wp_server_before.lat != wp_local_before.lat

        def handle_merge_dialog():
            QtTest.QTest.mouseClick(self.window.merge_dialog.overwriteBtn,
                                    QtCore.Qt.LeftButton)
            QtWidgets.QApplication.processEvents()

        QtCore.QTimer.singleShot(3000, handle_merge_dialog)
        QtTest.QTest.mouseClick(self.window.save_ft,
                                QtCore.Qt.LeftButton,
                                delay=1)
        QtWidgets.QApplication.processEvents()
        new_local_wp = self.window.waypoints_model.waypoint_data(0)
        assert wp_local_before.lat == new_local_wp.lat
        self.window.workLocallyCheckBox.setChecked(False)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        new_server_wp = self.window.waypoints_model.waypoint_data(0)
        assert wp_local_before.lat == new_server_wp.lat

    @pytest.mark.skip(reason="Need to fix test for dialog")
    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_save_keep_server_points(self, mockbox):
        self._login()
        self._activate_project_at_index(0)
        wp_server_before = self.window.waypoints_model.waypoint_data(0)
        self.window.workLocallyCheckBox.setChecked(True)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        wp_local = self.window.waypoints_model.waypoint_data(0)
        assert wp_local.lat == wp_server_before.lat
        self.window.waypoints_model.invert_direction()
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        wp_local_before = self.window.waypoints_model.waypoint_data(0)
        assert wp_server_before.lat != wp_local_before.lat

        def handle_merge_dialog():
            QtTest.QTest.mouseClick(self.window.merge_dialog.keepServerBtn,
                                    QtCore.Qt.LeftButton)
            QtWidgets.QApplication.processEvents()
            time.sleep(2)

        QtCore.QTimer.singleShot(3000, handle_merge_dialog)
        QtTest.QTest.mouseClick(self.window.save_ft,
                                QtCore.Qt.LeftButton,
                                delay=1)
        QtWidgets.QApplication.processEvents()
        new_local_wp = self.window.waypoints_model.waypoint_data(0)
        assert wp_local_before.lat != new_local_wp.lat
        assert new_local_wp.lat == wp_server_before.lat
        self.window.workLocallyCheckBox.setChecked(False)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        new_server_wp = self.window.waypoints_model.waypoint_data(0)
        assert wp_server_before.lat == new_server_wp.lat

    @pytest.mark.skip(reason="Need to fix test for dialog")
    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_save_merge_points(self, mockbox):
        self._login()
        self._activate_project_at_index(0)
        self.window.workLocallyCheckBox.setChecked(True)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        self.window.waypoints_model.invert_direction()
        merge_waypoints_model = None

        def handle_merge_dialog():
            nonlocal merge_waypoints_model
            self._select_waypoints(
                self.window.merge_dialog.localWaypointsTable)
            self._select_waypoints(
                self.window.merge_dialog.serverWaypointsTable)
            merge_waypoints_model = self.window.merge_dialog.merge_waypoints_model
            QtTest.QTest.mouseClick(self.window.merge_dialog.saveBtn,
                                    QtCore.Qt.LeftButton)
            QtWidgets.QApplication.processEvents()
            time.sleep(2)

        QtCore.QTimer.singleShot(3000, handle_merge_dialog)
        QtTest.QTest.mouseClick(self.window.save_ft,
                                QtCore.Qt.LeftButton,
                                delay=1)
        QtWidgets.QApplication.processEvents()
        new_local_wp = self.window.waypoints_model
        new_wp_count = len(merge_waypoints_model.waypoints)
        assert new_wp_count == 4
        assert len(new_local_wp.waypoints) == new_wp_count
        for wp_index in range(new_wp_count):
            assert new_local_wp.waypoint_data(
                wp_index).lat == merge_waypoints_model.waypoint_data(
                    wp_index).lat
        self.window.workLocallyCheckBox.setChecked(False)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        new_server_wp = self.window.waypoints_model
        assert len(new_server_wp.waypoints) == new_wp_count
        for wp_index in range(new_wp_count):
            assert new_server_wp.waypoint_data(
                wp_index).lat == merge_waypoints_model.waypoint_data(
                    wp_index).lat

    @pytest.mark.skip(reason="Need to fix test for dialog")
    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_fetch_from_server(self, mockbox):
        self._login()
        self._activate_project_at_index(0)
        wp_server_before = self.window.waypoints_model.waypoint_data(0)
        self.window.workLocallyCheckBox.setChecked(True)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        wp_local = self.window.waypoints_model.waypoint_data(0)
        assert wp_local.lat == wp_server_before.lat
        self.window.waypoints_model.invert_direction()
        wp_local_before = self.window.waypoints_model.waypoint_data(0)
        assert wp_server_before.lat != wp_local_before.lat

        def handle_merge_dialog():
            QtTest.QTest.mouseClick(self.window.merge_dialog.keepServerBtn,
                                    QtCore.Qt.LeftButton)
            QtWidgets.QApplication.processEvents()
            time.sleep(2)

        QtCore.QTimer.singleShot(3000, handle_merge_dialog)
        QtTest.QTest.mouseClick(self.window.fetch_ft,
                                QtCore.Qt.LeftButton,
                                delay=1)
        QtWidgets.QApplication.processEvents()
        new_local_wp = self.window.waypoints_model
        assert len(new_local_wp.waypoints) == 2
        assert new_local_wp.waypoint_data(0).lat == wp_server_before.lat
        self.window.workLocallyCheckBox.setChecked(False)
        QtWidgets.QApplication.processEvents()
        time.sleep(2)
        assert self.window.waypoints_model.waypoint_data(
            0).lat == wp_server_before.lat

    def _connect_to_mscolab(self):
        self.window.url.setEditText("http://localhost:8084")
        QtTest.QTest.mouseClick(self.window.connectMscolab,
                                QtCore.Qt.LeftButton)
        time.sleep(0.5)

    def _login(self, emailid="merge_waypoints_user", password="******"):
        self._connect_to_mscolab()
        self.window.emailid.setText(emailid)
        self.window.password.setText(password)
        QtTest.QTest.mouseClick(self.window.loginButton, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

    def _activate_project_at_index(self, index):
        item = self.window.listProjects.item(index)
        point = self.window.listProjects.visualItemRect(item).center()
        QtTest.QTest.mouseClick(self.window.listProjects.viewport(),
                                QtCore.Qt.LeftButton,
                                pos=point)
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseDClick(self.window.listProjects.viewport(),
                                 QtCore.Qt.LeftButton,
                                 pos=point)
        QtWidgets.QApplication.processEvents()

    def _select_waypoints(self, table):
        for row in range(table.model().rowCount()):
            table.selectRow(row)
            QtWidgets.QApplication.processEvents()