From fc5e3bc7ab5431476cacff074f8fb967388ad76e Mon Sep 17 00:00:00 2001 From: Giorgos Logiotatidis Date: Wed, 18 May 2016 11:00:07 +0300 Subject: [PATCH] Remove django_workable. --- careers/careers/tests/test_forms.py | 3 - careers/careers/tests/test_utils.py | 15 +-- careers/careers/tests/test_views.py | 12 -- careers/careers/urls.py | 2 - careers/careers/utils.py | 19 +-- careers/careers/views.py | 16 --- careers/django_workable/__init__.py | 0 careers/django_workable/admin.py | 9 -- .../django_workable/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/syncworkable.py | 93 --------------- .../migrations/0001_initial.py | 35 ------ .../django_workable/migrations/__init__.py | 0 careers/django_workable/models.py | 37 ------ careers/django_workable/tests/__init__.py | 30 ----- .../django_workable/tests/test_commands.py | 108 ------------------ careers/settings.py | 1 - 17 files changed, 7 insertions(+), 373 deletions(-) delete mode 100644 careers/django_workable/__init__.py delete mode 100644 careers/django_workable/admin.py delete mode 100644 careers/django_workable/management/__init__.py delete mode 100644 careers/django_workable/management/commands/__init__.py delete mode 100644 careers/django_workable/management/commands/syncworkable.py delete mode 100644 careers/django_workable/migrations/0001_initial.py delete mode 100644 careers/django_workable/migrations/__init__.py delete mode 100644 careers/django_workable/models.py delete mode 100644 careers/django_workable/tests/__init__.py delete mode 100644 careers/django_workable/tests/test_commands.py diff --git a/careers/careers/tests/test_forms.py b/careers/careers/tests/test_forms.py index 638332a5..2efbeed1 100644 --- a/careers/careers/tests/test_forms.py +++ b/careers/careers/tests/test_forms.py @@ -1,7 +1,6 @@ from careers.base.tests import TestCase from careers.careers.forms import PositionFilterForm from careers.careers.tests import PositionFactory as JobvitePositionFactory -from careers.django_workable.tests import PositionFactory as WorkablePositionFactory class PositionFilterFormTests(TestCase): @@ -14,13 +13,11 @@ def test_dynamic_position_type_choices(self): JobvitePositionFactory.create(job_type='Bar') JobvitePositionFactory.create(job_type='Baz') JobvitePositionFactory.create(job_type='Foo') - WorkablePositionFactory.create(job_type='Biff') form = PositionFilterForm() self.assertEqual(form.fields['position_type'].choices, [ ('', 'All Positions'), ('Bar', 'Bar'), # Alphabetical order ('Baz', 'Baz'), - ('Biff', 'Biff'), ('Foo', 'Foo'), ]) diff --git a/careers/careers/tests/test_utils.py b/careers/careers/tests/test_utils.py index de8819e6..fd52f2b8 100644 --- a/careers/careers/tests/test_utils.py +++ b/careers/careers/tests/test_utils.py @@ -2,50 +2,43 @@ from careers.careers import utils from careers.careers.tests import (CategoryFactory as JobviteCategoryFactory, PositionFactory as JobvitePositionFactory) -from careers.django_workable.tests import (CategoryFactory as WorkableCategoryFactory, - PositionFactory as WorkablePositionFactory) class GetAllPositionsTests(TestCase): def test_base(self): jobvite_1 = JobvitePositionFactory.create(title='Abc') jobvite_2 = JobvitePositionFactory.create(title='Def') - workable_1 = WorkablePositionFactory.create(title='Bcd') positions = utils.get_all_positions() - self.assertEqual(positions, [jobvite_1, workable_1, jobvite_2]) + self.assertEqual(positions, [jobvite_1, jobvite_2]) def test_filters(self): jobvite_1 = JobvitePositionFactory.create(title='aaa') JobvitePositionFactory.create(title='bbb') - workable_1 = WorkablePositionFactory.create(title='aaa') positions = utils.get_all_positions(filters={'title__contains': 'aaa'}) - self.assertEqual(set(positions), set([jobvite_1, workable_1])) + self.assertEqual(set(positions), set([jobvite_1])) def test_orderby(self): jobvite_1 = JobvitePositionFactory.create(title='aaa', location='b') - workable_1 = WorkablePositionFactory.create(title='bbb', location='c') jobvite_2 = JobvitePositionFactory.create(title='ccc', location='a') positions = utils.get_all_positions(order_by=lambda x: x.location) - self.assertEqual(positions, [jobvite_2, jobvite_1, workable_1]) + self.assertEqual(positions, [jobvite_2, jobvite_1]) class GetAllCategoriesTests(TestCase): def test_base(self): jobvite_1 = JobviteCategoryFactory.create(name='ccc') - workable_1 = WorkableCategoryFactory.create(name='bbb') jobvite_2 = JobviteCategoryFactory.create(name='aaa') categories = utils.get_all_categories() - self.assertEqual(categories, [jobvite_2.name, workable_1.name, jobvite_1.name]) + self.assertEqual(categories, [jobvite_2.name, jobvite_1.name]) class GetAllPositionTypesTests(TestCase): def test_base(self): JobvitePositionFactory.create(job_type='aaa') - WorkablePositionFactory.create(job_type='aaa') JobvitePositionFactory.create(job_type='bbb') job_types = utils.get_all_position_types() diff --git a/careers/careers/tests/test_views.py b/careers/careers/tests/test_views.py index 875db582..cff096f7 100644 --- a/careers/careers/tests/test_views.py +++ b/careers/careers/tests/test_views.py @@ -2,7 +2,6 @@ from careers.base.tests import TestCase from careers.careers.tests import PositionFactory as JobvitePositionFactory -from careers.django_workable.tests import PositionFactory as WorkablePositionFactory class PositionTests(TestCase): @@ -26,14 +25,3 @@ def test_position_case_sensitive_match(self): response = self.client.get(url, follow=True) self.assertEqual(response.status_code, 200) self.assertEqual(response.context_data['position'].job_id, job_id_2) - - -class WorkablePositionDetailViewTests(TestCase): - def test_base(self): - position_1 = WorkablePositionFactory.create(title='bbb') - position_2 = WorkablePositionFactory.create(category=position_1.category, title='aaa') - status = self.client.get( - reverse('careers.workable_position', kwargs={'shortcode': position_1.shortcode}), - follow=True) - self.assertEqual(status.context_data['positions'], [position_2, position_1]) - self.assertEqual(status.context_data['position'], position_1) diff --git a/careers/careers/urls.py b/careers/careers/urls.py index 2b70b690..f9332903 100644 --- a/careers/careers/urls.py +++ b/careers/careers/urls.py @@ -4,8 +4,6 @@ from .feeds import LatestPositionsFeed urlpatterns = [ - url(r'^position/wa/(?P[\w]+)$', views.WorkablePositionDetailView.as_view(), - name='careers.workable_position'), url(r'^position/(?P[\w]+)$', views.JobvitePositionDetailView.as_view(), name='careers.position'), url(r'^position/(?P[\w]+)$', views.JobvitePositionDetailView.as_view(), diff --git a/careers/careers/utils.py b/careers/careers/utils.py index e563ff92..a79c732b 100644 --- a/careers/careers/utils.py +++ b/careers/careers/utils.py @@ -1,7 +1,4 @@ -from itertools import chain - from django_jobvite import models as jobvite_models -from careers.django_workable import models as workable_models def get_all_positions(filters=None, order_by=None): @@ -13,22 +10,12 @@ def order_by_function(x): return x.title order_by = order_by_function - return ( - sorted( - chain(workable_models.Position.objects.filter(**filters), - jobvite_models.Position.objects.filter(**filters)), - key=order_by)) + return sorted(jobvite_models.Position.objects.filter(**filters), key=order_by) def get_all_categories(): - return ( - sorted(set( - chain(jobvite_models.Category.objects.values_list('name', flat=True), - workable_models.Category.objects.values_list('name', flat=True))))) + return sorted(set(jobvite_models.Category.objects.values_list('name', flat=True))) def get_all_position_types(): - return ( - sorted(set( - chain(jobvite_models.Position.objects.values_list('job_type', flat=True), - workable_models.Position.objects.values_list('job_type', flat=True))))) + return sorted(set(jobvite_models.Position.objects.values_list('job_type', flat=True))) diff --git a/careers/careers/views.py b/careers/careers/views.py index 0364a174..f288fffa 100644 --- a/careers/careers/views.py +++ b/careers/careers/views.py @@ -5,7 +5,6 @@ import utils from careers.careers.forms import PositionFilterForm -from careers.django_workable import models as workable_models def home(request): @@ -37,18 +36,3 @@ def get_context_data(self, **kwargs): filters={'category__name': context['position'].category.name}, order_by=lambda x: x.title) return context - - -class WorkablePositionDetailView(DetailView): - context_object_name = 'position' - model = workable_models.Position - template_name = 'careers/position.jinja' - slug_field = 'shortcode' - slug_url_kwarg = 'shortcode' - - def get_context_data(self, **kwargs): - context = super(WorkablePositionDetailView, self).get_context_data(**kwargs) - context['positions'] = utils.get_all_positions( - filters={'category__name': context['position'].category.name}, - order_by=lambda x: x.title) - return context diff --git a/careers/django_workable/__init__.py b/careers/django_workable/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/careers/django_workable/admin.py b/careers/django_workable/admin.py deleted file mode 100644 index 4f6856d4..00000000 --- a/careers/django_workable/admin.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.contrib import admin - -from .models import Position - - -class PositionAdmin(admin.ModelAdmin): - list_display = ('shortcode', 'title') - -admin.site.register(Position, PositionAdmin) diff --git a/careers/django_workable/management/__init__.py b/careers/django_workable/management/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/careers/django_workable/management/commands/__init__.py b/careers/django_workable/management/commands/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/careers/django_workable/management/commands/syncworkable.py b/careers/django_workable/management/commands/syncworkable.py deleted file mode 100644 index 0083f130..00000000 --- a/careers/django_workable/management/commands/syncworkable.py +++ /dev/null @@ -1,93 +0,0 @@ -from collections import defaultdict - -from django.core.management.base import BaseCommand, CommandError -from django.conf import settings - -import bleach -import requests - -from careers.django_workable.models import Category, Position - - -FIELD_MAP = { - 'shortcode': 'shortcode', - 'title': 'title', - 'shortlink': 'detail_url', - 'application_url': 'apply_url', - 'full_description': 'description', -} - -WORK_TYPE_MAP = { - 'Full-time': 'Regular (Full-Time)', - 'Part-time': 'Regular (Part-Time)', - 'Contract': 'Fixed-Term (MoFo)', -} - - -class Command(BaseCommand): - help = 'Fetch job listings from Workable' - - def handle(self, *args, **options): - if not getattr(settings, 'WORKABLE_URI', ''): - raise CommandError('You must setup WORKABLE_URI in settings first.') - - if not getattr(settings, 'WORKABLE_API_KEY', ''): - raise CommandError('You must setup WORKABLE_API_KEY too.') - - stats = defaultdict(lambda: 0) - saved_positions = [] - headers = {'Authorization': 'Bearer {0}'.format(settings.WORKABLE_API_KEY)} - jobs_response = requests.get(settings.WORKABLE_URI, headers=headers) - jobs = jobs_response.json().get('jobs', []) - - for job in jobs: - - if job['state'] != 'published': - continue - - job_data = requests.get( - '{0}{1}'.format(settings.WORKABLE_URI, job['shortcode']), - headers=headers) - job_data = job_data.json() - - try: - position = Position.objects.get(shortcode=job['shortcode']) - stats['updated_positions'] += 1 - except Position.DoesNotExist: - position = Position() - stats['new_positions'] += 1 - - for remote_field, local_field in FIELD_MAP.items(): - setattr(position, local_field, job_data[remote_field]) - - position.job_type = WORK_TYPE_MAP.get(job_data['employment_type'], - job_data['employment_type']) - - # If telecommute is on, add Remote - position.location = job_data['location']['city'] - if job_data['location']['telecommuting']: - position.location += ', Remote' - - # Everything workable is Mozilla Foundation for now. - category, created = Category.objects.get_or_create(name='Mozilla Foundation') - position.category = category - - # Bleach description - position.description = bleach.clean(position.description, - tags=bleach.ALLOWED_TAGS + ['br', 'p'], - strip=True) - - position.save() - saved_positions.append(position.shortcode) - - # Remove expired positions - stats['removed_positions'] = Position.objects.exclude(shortcode__in=saved_positions).count() - Position.objects.exclude(shortcode__in=saved_positions).delete() - stats['removed_categories'] = Category.objects.filter(position__isnull=True).count() - Category.objects.filter(position__isnull=True).delete() - - print ' -> Added: {0}'.format(stats['new_positions']) - print ' -> Updated: {0}'.format(stats['updated_positions']) - print ' -> Removed: {0}'.format(stats['removed_positions']) - print ' -> Removed Categories: {0}'.format(stats['removed_categories']) - print ' -> Total Workable.com positions: {0}'.format(Position.objects.all().count()) diff --git a/careers/django_workable/migrations/0001_initial.py b/careers/django_workable/migrations/0001_initial.py deleted file mode 100644 index 90855355..00000000 --- a/careers/django_workable/migrations/0001_initial.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='Category', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=100)), - ('slug', models.CharField(unique=True, max_length=100)), - ], - ), - migrations.CreateModel( - name='Position', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('shortcode', models.CharField(max_length=25)), - ('title', models.CharField(max_length=100)), - ('job_type', models.CharField(max_length=255)), - ('location', models.CharField(max_length=150, null=True, blank=True)), - ('detail_url', models.URLField()), - ('apply_url', models.URLField()), - ('description', models.TextField()), - ('category', models.ForeignKey(blank=True, to='django_workable.Category', null=True)), - ], - ), - ] diff --git a/careers/django_workable/migrations/__init__.py b/careers/django_workable/migrations/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/careers/django_workable/models.py b/careers/django_workable/models.py deleted file mode 100644 index 9b7e289c..00000000 --- a/careers/django_workable/models.py +++ /dev/null @@ -1,37 +0,0 @@ -from django.core.urlresolvers import reverse -from django.db import models -from django.template.defaultfilters import slugify - - -class Category(models.Model): - name = models.CharField(max_length=100) - slug = models.CharField(max_length=100, unique=True) - - def __str__(self): - return self.name - - def save(self, *args, **kwargs): - if not self.slug: - self.slug = slugify(self.name) - super(Category, self).save(*args, **kwargs) - - -class Position(models.Model): - shortcode = models.CharField(max_length=25) - title = models.CharField(max_length=100) - category = models.ForeignKey(Category, null=True, blank=True) - job_type = models.CharField(max_length=255) - location = models.CharField(max_length=150, null=True, blank=True) - detail_url = models.URLField() - apply_url = models.URLField() - description = models.TextField() - - def __str__(self): - return self.shortcode - - @property - def location_filter(self): - return self.location - - def get_absolute_url(self): - return reverse('careers.workable_position', kwargs={'shortcode': self.shortcode}) diff --git a/careers/django_workable/tests/__init__.py b/careers/django_workable/tests/__init__.py deleted file mode 100644 index d77e7596..00000000 --- a/careers/django_workable/tests/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -import factory -from factory import fuzzy - -from .. import models - - -class CategoryFactory(factory.DjangoModelFactory): - FACTORY_FOR = models.Category - name = factory.Sequence(lambda n: 'category {0}'.format(n)) - slug = factory.Sequence(lambda n: 'category-{0}'.format(n)) - - -class PositionFactory(factory.DjangoModelFactory): - FACTORY_FOR = models.Position - shortcode = factory.Sequence(lambda n: 'shortcode{0}'.format(n)) - category = factory.SubFactory(CategoryFactory) - title = factory.Sequence(lambda n: 'Job Title {0}'.format(n)) - job_type = fuzzy.FuzzyChoice(['Full-Time', 'Part-Time', 'Contractor', 'Intern']) - location = fuzzy.FuzzyChoice(['Mountain View', 'San Francisco', 'Remote', 'Toronto']) - description = factory.Sequence(lambda n: 'Job Description {0}'.format(n)) - - @factory.lazy_attribute - def apply_url(self): - url = 'https://mofo.workable.com/jobs/{0}/candidates/new' - return url.format(self.shortcode) - - @factory.lazy_attribute - def detail_url(self): - url = 'https://mofo.workable.com/j/{0}' - return url.format(self.shortcode) diff --git a/careers/django_workable/tests/test_commands.py b/careers/django_workable/tests/test_commands.py deleted file mode 100644 index f9ca1d0f..00000000 --- a/careers/django_workable/tests/test_commands.py +++ /dev/null @@ -1,108 +0,0 @@ -from django.core.management.base import CommandError -from django.test.utils import override_settings - -from mock import patch - -from careers.base.tests import TestCase -from careers.django_workable.management.commands import syncworkable -from careers.django_workable.models import Category, Position -from careers.django_workable.tests import CategoryFactory, PositionFactory - - -@override_settings(WORKABLE_URI='https://workable.example.com', - WORKABLE_API_KEY='secret') -class TestSyncWorkableCommand(TestCase): - def setUp(self): - self.command = syncworkable.Command() - self.spec = 'careers.django_workable.management.commands.syncworkable.requests' - - @override_settings(WORKABLE_URI=None) - def test_settings_workable_uri_does_not_exist(self): - with self.assertRaises(CommandError): - self.command.handle() - - @override_settings(WORKABLE_API_KEY=None) - def test_settings_workable_api_key_does_not_exist(self): - with self.assertRaises(CommandError): - self.command.handle() - - def test_unpublished_jobs_are_ignored(self): - data = {'jobs': [{'state': 'unpublished'}]} - with patch(self.spec) as requests_mock: - requests_mock.get().json().get().return_value = data - self.command.handle() - self.assertEqual(requests_mock.get.call_count, 2) - - def test_new_job_added(self): - data = {'jobs': [{'state': 'published', 'shortcode': 'foo'}]} - position_data = {'employment_type': 'type', - 'shortcode': 'foo', - 'title': 'title', - 'shortlink': 'http://foo.bar', - 'location': {'city': 'Paradise', 'telecommuting': True}, - 'application_url': 'http://example.com', - 'full_description': '

title

test'} - - with patch(self.spec) as requests_mock: - requests_mock.get().json.side_effect = [data, position_data] - self.command.handle() - - self.assertEqual(requests_mock.get.call_count, 3) - position = Position.objects.get(shortcode='foo') - self.assertEqual(position.job_type, 'type') - self.assertEqual(position.title, 'title') - self.assertEqual(position.detail_url, 'http://foo.bar') - self.assertEqual(position.apply_url, 'http://example.com') - self.assertEqual(position.location, 'Paradise, Remote') - self.assertEqual(position.description, 'title test') - - self.assertEqual(Position.objects.all().count(), 1) - - def test_existing_job_gets_updated(self): - category = CategoryFactory.create(name='test category') - PositionFactory.create(shortcode='foo', category=category) - data = {'jobs': [{'state': 'published', 'shortcode': 'foo'}]} - position_data = {'employment_type': 'type', - 'shortcode': 'foo', - 'title': 'title', - 'shortlink': 'http://foo.bar', - 'location': {'city': 'Paradise', 'telecommuting': True}, - 'application_url': 'http://example.com', - 'full_description': '

title

test'} - - with patch(self.spec) as requests_mock: - requests_mock.get().json.side_effect = [data, position_data] - - self.command.handle() - - self.assertEqual(requests_mock.get.call_count, 3) - position = Position.objects.get(shortcode='foo') - self.assertEqual(position.job_type, 'type') - self.assertEqual(position.title, 'title') - self.assertEqual(position.detail_url, 'http://foo.bar') - self.assertEqual(position.apply_url, 'http://example.com') - self.assertEqual(position.location, 'Paradise, Remote') - self.assertEqual(position.description, 'title test') - - self.assertEqual(Position.objects.all().count(), 1) - self.assertEqual(Category.objects.all().count(), 1) - self.assertEqual(Category.objects.all()[0].name, 'Mozilla Foundation') - - def test_known_job_type_converted(self): - data = {'jobs': [{'state': 'published', 'shortcode': 'foo'}]} - position_data = {'employment_type': 'foo', - 'shortcode': 'foo', - 'title': 'title', - 'shortlink': 'http://foo.bar', - 'location': {'city': 'Paradise', 'telecommuting': True}, - 'application_url': 'http://example.com', - 'full_description': '

title

test'} - - work_type_map_spec = ('careers.django_workable.management.commands' - '.syncworkable.WORK_TYPE_MAP') - with patch(work_type_map_spec, {'foo': 'bar'}): - with patch(self.spec) as requests_mock: - requests_mock.get().json.side_effect = [data, position_data] - self.command.handle() - position = Position.objects.get(shortcode='foo') - self.assertEqual(position.job_type, 'bar') diff --git a/careers/settings.py b/careers/settings.py index 0d080b03..461922a1 100644 --- a/careers/settings.py +++ b/careers/settings.py @@ -38,7 +38,6 @@ 'careers.base', 'careers.careers', 'careers.university', - 'careers.django_workable', 'careers.saml', # Third party apps