Skip to content
This repository has been archived by the owner on Mar 15, 2018. It is now read-only.

Commit

Permalink
Add lookup tool for websites (bug 1161865)
Browse files Browse the repository at this point in the history
  • Loading branch information
robhudson committed Jun 8, 2015
1 parent 849a09f commit 2a569ad
Show file tree
Hide file tree
Showing 18 changed files with 251 additions and 17 deletions.
9 changes: 4 additions & 5 deletions media/js/devreg/lookup-tool.js
Expand Up @@ -45,10 +45,9 @@ require(['prefetchManifest']);
}));

// Search suggestions.
$('#account-search').searchSuggestions($('#account-search-suggestions'),
processResults);
$('#app-search').searchSuggestions($('#app-search-suggestions'),
processResults);
$('#account-search').searchSuggestions($('#account-search-suggestions'), processResults);
$('#app-search').searchSuggestions($('#app-search-suggestions'), processResults);
$('#website-search').searchSuggestions($('#website-search-suggestions'), processResults);

// Show All Results.
var searchTerm = '';
Expand Down Expand Up @@ -114,7 +113,7 @@ require(['prefetchManifest']);
id: item.id,
email: item.email || '',
name: item.name || item.display_name,
status: item.status
status: item.status || 'none'
};
if (d.url && d.id) {
d.name = escape_(d.name);
Expand Down
3 changes: 3 additions & 0 deletions migrations/913-websites-lookup-perms.sql
@@ -0,0 +1,3 @@
-- Changing Websites:Review to Websites:* and removing duplicate Stats:View.
UPDATE groups SET rules='Apps:*,Websites:*,Users:Edit,Stats:View,AdminTools:View,AccountLookup:View,AppLookup:View,Lookup:View' WHERE name='Staff';
UPDATE groups SET rules=CONCAT(rules, ',WebsiteLookup:View') WHERE name IN ('Staff', 'Support Staff', 'Carriers and Operators');
11 changes: 9 additions & 2 deletions mkt/lookup/helpers.py
Expand Up @@ -15,15 +15,13 @@ def format_currencies(context, currencies):
return jinja2.Markup(cs)


# page_type is used for setting the link 'sel' class (activity/purchases)
@register.function
def user_header(account, title, is_admin=False, page_type=''):
t = env.get_template('lookup/helpers/user_header.html')
return jinja2.Markup(t.render({'account': account, 'is_admin': is_admin,
'title': title, 'page_type': page_type}))


# page_type is used for setting the link 'sel' class
@register.function
@jinja2.contextfunction
def app_header(context, app, page_type=''):
Expand All @@ -41,6 +39,15 @@ def app_header(context, app, page_type=''):
'is_operator': is_operator}))


@register.function
@jinja2.contextfunction
def website_header(context, website, page_type=''):
t = env.get_template('lookup/helpers/website_header.html')

return jinja2.Markup(t.render({'website': website,
'page_type': page_type}))


@register.function
@jinja2.contextfunction
def is_operator(context):
Expand Down
11 changes: 11 additions & 0 deletions mkt/lookup/serializers.py
Expand Up @@ -4,6 +4,7 @@

import mkt
from mkt.webapps.serializers import ESAppSerializer
from mkt.websites.serializers import ESWebsiteSerializer


class AppLookupSerializer(ESAppSerializer):
Expand All @@ -30,3 +31,13 @@ def get_app_status(self, obj):
else:
status = mkt.STATUS_CHOICES_API_v2[obj.status]
return status


class WebsiteLookupSerializer(ESWebsiteSerializer):
url = serializers.SerializerMethodField('get_website_summary_url')

class Meta(ESWebsiteSerializer.Meta):
fields = ['id', 'name', 'url']

def get_website_summary_url(self, obj):
return reverse('lookup.website_summary', args=[obj.id])
15 changes: 15 additions & 0 deletions mkt/lookup/templates/lookup/helpers/website_header.html
@@ -0,0 +1,15 @@
<h1>
{{ _('Website Lookup results for') }}
<a href="{{ website.get_url_path() }}"
title="{{ _('Website Detail') }}">{{ website.name }}</a>
({{ website.pk }})
</h1>

<section class="column-a">
<img src="{{ website.get_icon_url(64) }}">
<nav class="shortcuts" role="navigation">
<ul>
{# TODO: Add "Edit Listing" for admins/staff (bug 1161867) #}
</ul>
</nav>
</section>
3 changes: 3 additions & 0 deletions mkt/lookup/templates/lookup/home.html
Expand Up @@ -13,4 +13,7 @@
{% if action_allowed('AppLookup', 'View') %}
{% include 'lookup/includes/app_search.html' %}
{% endif %}
{% if action_allowed('WebsiteLookup', 'View') %}
{% include 'lookup/includes/website_search.html' %}
{% endif %}
{% endblock %}
13 changes: 13 additions & 0 deletions mkt/lookup/templates/lookup/includes/website_search.html
@@ -0,0 +1,13 @@
<section class="island">
<form method="post" class="lookup-search-form" id="website-search-form">
{{ csrf() }}
<label>
{{ _('Website Lookup') }}
</label>
<input type="search" id="website-search" name="q" autocomplete="off">
<input type="hidden" id="website-lang" name="lang" autocomplete="off" value="{{ request.LANG|default('en-US') }}">
<button>{{ _('Search') }}</button>
<ul id="website-search-suggestions" class="search-suggestions"
data-src="{{ url('lookup.website_search') }}"></ul>
</form>
</section>
56 changes: 56 additions & 0 deletions mkt/lookup/templates/lookup/website_summary.html
@@ -0,0 +1,56 @@
{% extends 'lookup/base.html' %}

{% block breadcrumbs %}
{% endblock %}

{% block content %}
{% include 'lookup/includes/website_search.html' %}

<section class="island c transaction-lookup">
{{ website_header(website, 'summary') }}

<section class="column-b">
<dl>
<dt>{{ _('Title') }}</dt>
<dd>{{ website.title }}</dd>
</dl>
<dl>
<dt>{{ _('Name - Short Name') }}</dt>
<dd>{{ website.name }} - {{ website.short_name }}</dd>
</dl>
<dl>
<dt>{{ _('Description') }}</dt>
<dd>{{ website.description }}</dd>
</dl>
<dl>
<dt>{{ _('URL') }}</dt>
<dd>{{ website.url }}</dd>
</dl>
<dl>
<dt>{{ _('Mobile URL') }}</dt>
<dd>{{ website.mobile_url }}</dd>
</dl>
<dl>
<dt>{{ _('Keywords') }}</dt>
<dd>{{ website.keywords_list|join(', ') }}</dd>
</dl>
<dl>
<dt>{{ _('Preferred Regions') }}</dt>
<dd>{{ website.get_preferred_regions(sort_by='name')|map(attribute='name')|join(', ') }}</dd>
</dl>
<dl>
<dt>{{ _('Categories') }}</dt>
<dd>{{ website.categories|categories_names|join(', ') }}</dd>
</dl>
<dl>
<dt>{{ _('Status') }}</dt>
<dd>
{{ mkt.STATUS_CHOICES[website.status] }}
{% if website.is_disabled %}
({{ _('disabled') }})
{% endif %}
</dd>
</dl>
</section>

{% endblock %}
27 changes: 27 additions & 0 deletions mkt/lookup/tests/test_serializers.py
@@ -0,0 +1,27 @@
from django.core.urlresolvers import reverse

from nose.tools import eq_

from mkt.lookup.serializers import WebsiteLookupSerializer
from mkt.site.tests import ESTestCase
from mkt.websites.indexers import WebsiteIndexer
from mkt.websites.utils import website_factory


class TestWebsiteLookupSerializer(ESTestCase):

def setUp(self):
self.website = website_factory()
self.refresh('website')

def serialize(self):
obj = WebsiteIndexer.search().filter(
'term', id=self.website.pk).execute().hits[0]
return WebsiteLookupSerializer(obj).data

def test_basic(self):
data = self.serialize()
eq_(data['id'], self.website.id)
eq_(data['name'], {'en-US': self.website.name})
eq_(data['url'],
reverse('lookup.website_summary', args=[self.website.id]))
43 changes: 40 additions & 3 deletions mkt/lookup/tests/test_views.py
Expand Up @@ -18,9 +18,9 @@
import mkt.site.tests
from mkt.abuse.models import AbuseReport
from mkt.access.models import Group, GroupUser
from mkt.constants.payments import (
FAILED, PENDING, PROVIDER_BANGO, PROVIDER_REFERENCE,
SOLITUDE_REFUND_STATUSES)
from mkt.constants.payments import (FAILED, PENDING, PROVIDER_BANGO,
PROVIDER_REFERENCE,
SOLITUDE_REFUND_STATUSES)
from mkt.developers.models import (ActivityLog, AddonPaymentAccount,
PaymentAccount, SolitudeSeller)
from mkt.developers.providers import get_provider
Expand All @@ -38,6 +38,7 @@
from mkt.tags.models import Tag
from mkt.users.models import UserProfile
from mkt.webapps.models import AddonUser, Webapp
from mkt.websites.utils import website_factory


class SummaryTest(TestCase):
Expand Down Expand Up @@ -293,6 +294,7 @@ class SearchTestMixin(object):

def search(self, expect_objects=True, **data):
res = self.client.get(self.url, data)
eq_(res.status_code, 200)
data = json.loads(res.content)
if expect_objects:
assert len(data['objects']), 'should be more than 0 objects'
Expand Down Expand Up @@ -1174,3 +1176,38 @@ def test_logs(self):
doc = pq(res.content)
assert 'manifest updated' in doc('li.item').eq(0).text()
assert 'Comment on' in doc('li.item').eq(1).text()


class TestWebsiteSearch(ESTestCase, SearchTestMixin):
fixtures = fixture('user_support_staff', 'user_999')

def setUp(self):
super(TestWebsiteSearch, self).setUp()
self.url = reverse('lookup.website_search')
self.website = website_factory()
self.refresh('website')
self.login('support-staff@mozilla.com')

def search(self, *args, **kwargs):
if 'lang' not in kwargs:
kwargs.update({'lang': 'en-US'})
return super(TestWebsiteSearch, self).search(*args, **kwargs)

def verify_result(self, data):
eq_(data['objects'][0]['id'], self.website.pk)
eq_(data['objects'][0]['name'], self.website.name.localized_string)
eq_(data['objects'][0]['url'], reverse('lookup.website_summary',
args=[self.website.pk]))

def test_auth_required(self):
self.client.logout()
res = self.client.get(self.url)
eq_(res.status_code, 403)

def test_by_name(self):
data = self.search(q=self.website.name.localized_string)
self.verify_result(data)

def test_by_id(self):
data = self.search(q=self.website.pk)
self.verify_result(data)
11 changes: 11 additions & 0 deletions mkt/lookup/urls.py
Expand Up @@ -27,6 +27,14 @@
)


# These views all start with website/<ID>.
website_patterns = patterns(
'',
url(r'^summary$', views.website_summary,
name='lookup.website_summary'),
)


# These views all start with transaction ID.
transaction_patterns = patterns(
'',
Expand All @@ -49,7 +57,10 @@
name='lookup.transaction_search'),
url(r'^user_search$', views.user_search,
name='lookup.user_search'),
url(r'^website_search$', views.WebsiteLookupSearchView.as_view(),
name='lookup.website_search'),
(r'^app/(?P<addon_id>[^/]+)/', include(app_patterns)),
(r'^website/(?P<addon_id>[^/]+)/', include(website_patterns)),
(r'^transaction/(?P<tx_uuid>[^/]+)/',
include(transaction_patterns)),
(r'^user/(?P<user_id>[^/]+)/', include(user_patterns)),
Expand Down
32 changes: 31 additions & 1 deletion mkt/lookup/views.py
Expand Up @@ -33,16 +33,19 @@
from mkt.developers.views_payments import _redirect_to_bango_portal
from mkt.lookup.forms import (APIFileStatusForm, APIStatusForm, DeleteUserForm,
TransactionRefundForm, TransactionSearchForm)
from mkt.lookup.serializers import AppLookupSerializer
from mkt.lookup.serializers import AppLookupSerializer, WebsiteLookupSerializer
from mkt.prices.models import AddonPaymentData, Refund
from mkt.purchase.models import Contribution
from mkt.reviewers.models import QUEUE_TARAKO
from mkt.search.filters import SearchQueryFilter
from mkt.search.views import SearchView
from mkt.site.decorators import json_view, login_required, permission_required
from mkt.site.utils import paginate
from mkt.tags.models import attach_tags
from mkt.users.models import UserProfile
from mkt.webapps.models import Webapp
from mkt.websites.models import Website
from mkt.websites.views import WebsiteSearchView


log = commonware.log.getLogger('z.lookup')
Expand Down Expand Up @@ -314,6 +317,18 @@ def app_summary(request, addon_id):
})


@login_required
@permission_required([('WebsiteLookup', 'View')])
def website_summary(request, addon_id):
website = get_object_or_404(Website, pk=addon_id)
if not hasattr(website, 'keywords_list'):
attach_tags([website], m2m_name='keywords')

return render(request, 'lookup/website_summary.html', {
'website': website,
})


@login_required
@permission_required([('AccountLookup', 'View')])
def app_activity(request, addon_id):
Expand Down Expand Up @@ -443,6 +458,21 @@ def get_paginate_by(self, *args, **kwargs):
**kwargs)


class WebsiteLookupSearchView(WebsiteSearchView):
permission_classes = [GroupPermission('WebsiteLookup', 'View')]
filter_backends = [SearchQueryFilter]
serializer_class = WebsiteLookupSerializer
paginate_by = lkp.SEARCH_LIMIT
max_paginate_by = lkp.MAX_RESULTS

def get_paginate_by(self, *args, **kwargs):
if self.request.GET.get(self.paginate_by_param) == 'max':
return self.max_paginate_by
else:
return super(WebsiteLookupSearchView,
self).get_paginate_by(*args, **kwargs)


def _app_summary(user_id):
sql = """
select currency,
Expand Down
2 changes: 1 addition & 1 deletion mkt/site/fixtures/data/user_operator.json
Expand Up @@ -19,7 +19,7 @@
"pk": 322,
"model": "access.group",
"fields": {
"rules": "AppLookup:View,Lookup:View,Operators:*",
"rules": "AppLookup:View,WebsiteLookup:View,Lookup:View,Operators:*",
"notes": "",
"modified": "2012-05-22 17:53:57",
"name": "Operators",
Expand Down
2 changes: 1 addition & 1 deletion mkt/site/fixtures/data/user_support_staff.json
Expand Up @@ -19,7 +19,7 @@
"pk": 50059,
"model": "access.group",
"fields": {
"rules": "AccountLookup:View,Apps:Configure,Transaction:Refund,Transaction:View,Lookup:View,AppLookup:View,BangoPortal:Redirect",
"rules": "AccountLookup:View,Apps:Configure,Transaction:Refund,Transaction:View,Lookup:View,AppLookup:View,WebsiteLookup:View,BangoPortal:Redirect",
"notes": "",
"modified": "2012-05-22 17:53:57",
"name": "Support Staff",
Expand Down
2 changes: 1 addition & 1 deletion mkt/site/fixtures/data/users.json
Expand Up @@ -167,7 +167,7 @@
"pk": 50057,
"model": "access.group",
"fields": {
"rules": "AccountLookup:View,Apps:Configure,Transaction:View,Transaction:Refund,Lookup:View,AppLookup:View",
"rules": "AccountLookup:View,Apps:Configure,Transaction:View,Transaction:Refund,Lookup:View,AppLookup:View,WebsiteLookup:View",
"notes": "",
"modified": "2012-05-22 17:53:57",
"name": "Support Staff",
Expand Down

0 comments on commit 2a569ad

Please sign in to comment.