From 8d20d0fa7ed226735daba4b0507cf0037860af71 Mon Sep 17 00:00:00 2001 From: Giovane Date: Mon, 21 Sep 2015 18:10:17 -0300 Subject: #442 Creates feedback service that create tickets on leap web. --- .../pixelated/adapter/services/feedback_service.py | 17 ++++++++++++ service/pixelated/application.py | 3 +- service/pixelated/config/services.py | 5 ++++ service/pixelated/resources/feedback_resource.py | 32 ++++++++++++++++++++++ service/pixelated/resources/root_resource.py | 5 +++- service/test/integration/test_feedback_service.py | 14 ++++++++++ .../test/support/integration/app_test_client.py | 6 +++- .../test/unit/resources/test_feedback_resource.py | 27 ++++++++++++++++++ 8 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 service/pixelated/adapter/services/feedback_service.py create mode 100644 service/pixelated/resources/feedback_resource.py create mode 100644 service/test/integration/test_feedback_service.py create mode 100644 service/test/unit/resources/test_feedback_resource.py diff --git a/service/pixelated/adapter/services/feedback_service.py b/service/pixelated/adapter/services/feedback_service.py new file mode 100644 index 00000000..87363b12 --- /dev/null +++ b/service/pixelated/adapter/services/feedback_service.py @@ -0,0 +1,17 @@ +import requests + + +class FeedbackService(object): + def __init__(self, leap_session): + self.leap_session = leap_session + + def open_ticket(self, feedback): + account_mail = self.leap_session.account_email() + data = { + "ticket[comments_attributes][0][body]": feedback, + "ticket[subject]": "Feedback user-agent from {0}".format(account_mail), + "ticket[email]": account_mail, + "ticket[regarding_user]": account_mail + } + + return requests.post("https://pixelated.wazokazi.is/tickets", files=data, verify=False) diff --git a/service/pixelated/application.py b/service/pixelated/application.py index e7afa341..1194a1a8 100644 --- a/service/pixelated/application.py +++ b/service/pixelated/application.py @@ -42,7 +42,8 @@ def start_user_agent(loading_app, host, port, sslkey, sslcert, leap_home, leap_s services.keymanager, services.search_engine, services.mail_service, - services.draft_service) + services.draft_service, + services.feedback_service) if sslkey and sslcert: reactor.listenSSL(port, PixelatedSite(resource), _ssl_options(sslkey, sslcert), interface=host) diff --git a/service/pixelated/config/services.py b/service/pixelated/config/services.py index dde8c55d..41a357dc 100644 --- a/service/pixelated/config/services.py +++ b/service/pixelated/config/services.py @@ -7,6 +7,7 @@ from pixelated.adapter.services.draft_service import DraftService from pixelated.adapter.listeners.mailbox_indexer_listener import listen_all_mailboxes from twisted.internet import defer from pixelated.adapter.search.index_storage_key import SearchIndexStorageKey +from pixelated.adapter.services.feedback_service import FeedbackService class Services(object): @@ -33,6 +34,7 @@ class Services(object): self.keymanager = leap_session.nicknym self.draft_service = self.setup_draft_service(leap_session.mail_store) + self.feedback_service = self.setup_feedback_service(leap_session) yield self.index_all_mails() @@ -68,3 +70,6 @@ class Services(object): def setup_search_index_storage_key(self, soledad): return SearchIndexStorageKey(soledad) + + def setup_feedback_service(self, leap_session): + return FeedbackService(leap_session) diff --git a/service/pixelated/resources/feedback_resource.py b/service/pixelated/resources/feedback_resource.py new file mode 100644 index 00000000..b989b273 --- /dev/null +++ b/service/pixelated/resources/feedback_resource.py @@ -0,0 +1,32 @@ +# +# Copyright (c) 2015 ThoughtWorks, Inc. +# +# Pixelated is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pixelated is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with Pixelated. If not, see . +import json + +from twisted.web.resource import Resource +from pixelated.resources import respond_json + + +class FeedbackResource(Resource): + isLeaf = True + + def __init__(self, feedback_service): + Resource.__init__(self) + self.feedback_service = feedback_service + + def render_POST(self, request): + feedback = json.loads(request.content.read()).get('feedback') + self.feedback_service.open_ticket(feedback) + return respond_json({}, request) diff --git a/service/pixelated/resources/root_resource.py b/service/pixelated/resources/root_resource.py index c1111269..8b536450 100644 --- a/service/pixelated/resources/root_resource.py +++ b/service/pixelated/resources/root_resource.py @@ -1,7 +1,9 @@ import os +import requests from pixelated.resources.attachments_resource import AttachmentsResource from pixelated.resources.contacts_resource import ContactsResource from pixelated.resources.features_resource import FeaturesResource +from pixelated.resources.feedback_resource import FeedbackResource from pixelated.resources.mail_resource import MailResource from pixelated.resources.mails_resource import MailsResource from pixelated.resources.tags_resource import TagsResource @@ -21,7 +23,7 @@ class RootResource(Resource): return self return Resource.getChild(self, path, request) - def initialize(self, keymanager, search_engine, mail_service, draft_service): + def initialize(self, keymanager, search_engine, mail_service, draft_service, feedback_service): self.putChild('assets', File(self._static_folder)) self.putChild('keys', KeysResource(keymanager)) self.putChild('attachment', AttachmentsResource(mail_service)) @@ -30,6 +32,7 @@ class RootResource(Resource): self.putChild('tags', TagsResource(search_engine)) self.putChild('mails', MailsResource(mail_service, draft_service)) self.putChild('mail', MailResource(mail_service)) + self.putChild('feedback', FeedbackResource(feedback_service)) def _get_static_folder(self): static_folder = os.path.abspath(os.path.join(os.path.abspath(__file__), "..", "..", "..", "web-ui", "app")) diff --git a/service/test/integration/test_feedback_service.py b/service/test/integration/test_feedback_service.py new file mode 100644 index 00000000..595a29ce --- /dev/null +++ b/service/test/integration/test_feedback_service.py @@ -0,0 +1,14 @@ +import unittest +from mockito import when +from twisted.internet import defer +from test.support.integration import AppTestClient + + +class TestFeedbackService(unittest.TestCase, AppTestClient): + @defer.inlineCallbacks + def test_open_ticket(self): + yield self.start_client() + when(self.leap_session).account_email().thenReturn("text@pixelated-project.org") + response = self.feedback_service.open_ticket("Pixelated is awesome!") + + self.assertEquals(response.status_code, 200) diff --git a/service/test/support/integration/app_test_client.py b/service/test/support/integration/app_test_client.py index 3245e728..ff5af0a7 100644 --- a/service/test/support/integration/app_test_client.py +++ b/service/test/support/integration/app_test_client.py @@ -31,6 +31,7 @@ from twisted.internet import reactor, defer from twisted.internet.defer import succeed from twisted.web.resource import getChildForRequest # from twisted.web.server import Site as PixelatedSite +from pixelated.adapter.services.feedback_service import FeedbackService from pixelated.config.site import PixelatedSite from pixelated.adapter.mailstore import LeapMailStore @@ -74,13 +75,16 @@ class AppTestClient(object): self.account = IMAPAccount(self.ACCOUNT, self.soledad, account_ready_cb) yield account_ready_cb self.draft_service = DraftService(self.mail_store) + self.leap_session = mock() + self.feedback_service = FeedbackService(self.leap_session) self.mail_service = self._create_mail_service(self.mail_sender, self.mail_store, self.search_engine) mails = yield self.mail_service.all_mails() self.search_engine.index_mails(mails) self.resource = RootResource() - self.resource.initialize(self.keymanager, self.search_engine, self.mail_service, self.draft_service) + self.resource.initialize( + self.keymanager, self.search_engine, self.mail_service, self.draft_service, self.feedback_service) def _render(self, request, as_json=True): def get_str(_str): diff --git a/service/test/unit/resources/test_feedback_resource.py b/service/test/unit/resources/test_feedback_resource.py new file mode 100644 index 00000000..63e6efc4 --- /dev/null +++ b/service/test/unit/resources/test_feedback_resource.py @@ -0,0 +1,27 @@ +import json +from mockito import verify, mock, when +from twisted.trial import unittest +from twisted.web.test.requesthelper import DummyRequest +from pixelated.resources.feedback_resource import FeedbackResource +from test.unit.resources import DummySite + + +class TestFeedbackResource(unittest.TestCase): + def setUp(self): + self.feedback_service = mock() + self.web = DummySite(FeedbackResource(self.feedback_service)) + + def test_sends_feedback_to_leap_web(self): + request = DummyRequest(['/feedback']) + request.method = 'POST' + content = mock() + when(content).read().thenReturn(json.dumps({'feedback': 'Pixelated is awesome!'})) + request.content = content + + d = self.web.get(request) + + def assert_posted_feedback_to_leap_web(_): + verify(self.feedback_service).open_ticket('Pixelated is awesome!') + + d.addCallback(assert_posted_feedback_to_leap_web) + return d -- cgit v1.2.3