diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 00000000..2c95141d --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,19 @@ +# This action uses commitlint to lint commit messages and check for the required guidelines +# as given by the config file commitlint.config.js + +name: Check Commit Messages + +on: + pull_request: + branches: [ develop ] + +jobs: + check-commits: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2.3.1 + with: + fetch-depth: 0 + - uses: actions/setup-node@v2.1.0 + - run: yarn add @commitlint/{config-conventional,cli} + - run: yarn run commitlint --from HEAD~${{ github.event.pull_request.commits }} --to HEAD diff --git a/.travis.yml b/.travis.yml index fba9dae0..003db81c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ sudo: true language: python +dist: bionic env: - MOZ_HEADLESS=1 @@ -11,6 +12,8 @@ services: python: - "3.6" + - "3.7" + before_install: - wget https://github.com/mozilla/geckodriver/releases/download/v0.20.1/geckodriver-v0.20.1-linux64.tar.gz - tar -xzvf geckodriver-v0.20.1-linux64.tar.gz @@ -20,7 +23,10 @@ install: - pip install coveralls==0.4.4 - sudo apt-get install python-gdal before_script: + - export GOOGLE_MAPS_API_KEY=$GOOGLE_MAPS_API_KEY - export SECRET_KEY=foobarbaz +# - curl -o ipdb.tar.gz https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key=$MAXMIND_LICENSE_KEY&suffix=tar.gz +# - tar -xzf ipdb.tar.gz -C systers_portal/ - psql -c "CREATE DATABASE systersdb;" -U postgres script: - coverage run systers_portal/manage.py test --settings=systers_portal.settings.testing @@ -41,4 +47,4 @@ notifications: on_failure: always on_start: false after_success: - coveralls --rcfile=.coveragerc + coveralls --rcfile=.coveragerc \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 8d001dd6..d103595b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,33 @@ -FROM python:2.7 +# getting the base Image +FROM python:3.6 + MAINTAINER Ana Balica + +# Updated by +LABEL HUSSAIN="husainattar110@gmail.com" + EXPOSE 8000 +# Initializing the working directory WORKDIR /usr/src + RUN mkdir portal + RUN cd portal + +# Re-Initializing the working directory WORKDIR /usr/src/portal + +# Copy the requirement.txt for installing COPY requirements/prod.txt /usr/src/portal/requirements/prod.txt -RUN pip install -r requirements/prod.txt +COPY requirements/dev.txt /usr/src/portal/requirements/dev.txt + +# Installing the requirements +RUN pip install -r requirements/dev.txt +# Installing the GDAL Library +# RUN apt-get install python-gdal +RUN apt-get update +RUN apt-get install -y software-properties-common +RUN add-apt-repository ppa:ubuntugis/ppa +RUN apt-get install -y gdal-bin python-gdal python3-gdal diff --git a/README.md b/README.md index 8e666689..3fbbad3a 100644 --- a/README.md +++ b/README.md @@ -146,12 +146,30 @@ production at the moment. It may be configured to do so in the future. 1. **This step will require the Django SECRET_KEY.** Run `docker run -e SECRET_KEY=foobarbaz portal_web`. 1. Run `docker-compose run web python systers_portal/manage.py migrate`. + + * After above command now Run `docker-compose run web python systers_portal/manage.py makemigrations` + for complete migration and then re-run `docker-compose run web python systers_portal/manage.py migrate`. + * Note: If you face any error like **Docker cannot link or db not running** + then run the following command in another terminal `docker-compose up db` + and again run the above following command + 1. Run `docker-compose run web python systers_portal/manage.py cities_light` for downloading and importing data for django-cities-light. 1. *Optional:* Run `docker-compose run web python systers_portal/manage.py createsuperuser` if you wish to create a superuser to access the admin panel. + + For working with database open up new terminal and run `docker-compose run db bash` + and then run `psql -U postgres -d postgres -h db` to enter in postgres db. + Run `\dt` for checking tables and `\q` for exiting the postgres terminal + and stop the container's bash using CTRL+D. + +1. Navigate to `systers_portal/systers_portal/settings/base.py` file and change to `ALLOWED_HOST=['O.O.O.O']` + so that we can access the docker-container from any ip address. + 1. Run `docker-compose up` to start the webserver for the Django Systers Portal project. + * Note If you face any error like **portal_web cannot start service web** then run + following command `service docker restart` then again run the above following command 1. Systers Portal should be running on port 8000. * If you are on Linux, enter `http://0.0.0.0:8000` in your browser. * If you are using boot2docker on Windows or Mac OS X, enter diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 00000000..4344537b --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1,37 @@ +module.exports = { + parserPreset: 'conventional-changelog-conventionalcommits', + rules: { + 'body-leading-blank': [1, 'always'], + 'body-max-line-length': [2, 'always', 100], + 'footer-leading-blank': [1, 'always'], + 'footer-max-line-length': [2, 'always', 100], + 'header-max-length': [2, 'always', 100], + 'scope-case': [2, 'always', 'lower-case'], + 'subject-case': [ + 2, + 'always', + ['sentence-case', 'upper-case'] + ], + 'subject-empty': [2, 'never'], + 'subject-full-stop': [2, 'never', '.'], + 'type-case': [2, 'always', 'lower-case'], + 'type-empty': [2, 'never'], + 'type-enum': [ + 2, + 'always', + [ + 'build', + 'chore', + 'ci', + 'docs', + 'feat', + 'fix', + 'perf', + 'refactor', + 'revert', + 'style', + 'test' + ] + ] + } +}; diff --git a/docker-compose.yml b/docker-compose.yml index 57b83146..84610d16 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,14 +1,19 @@ db: image: postgres:9.4 + ports: + - "5432:5432" + environment: + - POSTGRES_HOST_AUTH_METHOD=trust + web: build: . command: python systers_portal/manage.py runserver 0.0.0.0:8000 volumes: - - .:/usr/src/portal + - .:/usr/src/portal ports: - - "8000:8000" + - "8000:8000" links: - - db + - db environment: - - DJANGO_SETTINGS_MODULE=systers_portal.settings.docker - + - SECRET_KEY=foobarbaz + - DJANGO_SETTINGS_MODULE=systers_portal.settings.docker diff --git a/requirements/dev.txt b/requirements/dev.txt index 997e4b27..98f729cd 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -1,15 +1,15 @@ -r prod.txt -Sphinx==1.6.5 -coverage==4.4.1 -django-nose==1.4.5 -flake8==2.4.1 -sphinx-rtd-theme==0.2.4 -pylint==1.9.0 -pytest==3.5.1 -pytest-cov==2.5.1 -pytest-django==3.2.1 -pytest-pylint==0.9.0 -selenium==3.12.0 -djangorestframework==3.8.2 -geopy==1.15.0 -pinax-notifications==5.0.3 +Sphinx==3.1.2 +coverage==5.2.1 +django-nose==1.4.6 +flake8==3.8.3 +sphinx-rtd-theme==0.5.0 +pylint==2.5.3 +pytest==5.4.3 +pytest-cov==2.10.0 +pytest-django==3.9.0 +pytest-pylint==0.17.0 +selenium==3.141.0 +djangorestframework==3.11.0 +geopy==2.0.0 +pinax-notifications==6.0.0 \ No newline at end of file diff --git a/requirements/prod.txt b/requirements/prod.txt index 2cfe1714..0568d329 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -1,12 +1,14 @@ -Django==1.11.6 -Pillow==4.3.0 -django-allauth==0.33.0 -django-braces==1.11.0 -django-cities-light==3.3.0 -django-ckeditor==5.3.1 -django-crispy-forms==1.7.0 -django-guardian==1.4.9 -django-imagekit==4.0.1 -djangocms-admin-style==1.2.7 -psycopg2==2.7.3.2 -python3-openid==3.1.0 +Django==3.0.8 +Pillow==7.2.0 +django-allauth==0.42.0 +django-braces==1.14.0 +django-cities-light==3.6.0 +django-ckeditor==5.9.0 +django-crispy-forms==1.9.2 +django-guardian==2.3.0 +django-imagekit==4.0.2 +psycopg2==2.8.5 +python3-openid==3.2.0 +geoip2==4.0.1 +django-ipware==3.0.0 + diff --git a/setup.cfg b/setup.cfg index ce17d8a0..44b37ab6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,4 +1,4 @@ [flake8] -ignore = F403 +ignore = F403, F405 exclude = .git,docs/*,systers_portal/manage.py,wsgi.py,migrations max-line-length = 100 diff --git a/systers_portal/GeoLite2-City_20200616/COPYRIGHT.txt b/systers_portal/GeoLite2-City_20200616/COPYRIGHT.txt new file mode 100644 index 00000000..9c5395fd --- /dev/null +++ b/systers_portal/GeoLite2-City_20200616/COPYRIGHT.txt @@ -0,0 +1 @@ +Database and Contents Copyright (c) 2020 MaxMind, Inc. diff --git a/systers_portal/GeoLite2-City_20200616/GeoLite2-City.mmdb b/systers_portal/GeoLite2-City_20200616/GeoLite2-City.mmdb new file mode 100644 index 00000000..b092199d Binary files /dev/null and b/systers_portal/GeoLite2-City_20200616/GeoLite2-City.mmdb differ diff --git a/systers_portal/GeoLite2-City_20200616/LICENSE.txt b/systers_portal/GeoLite2-City_20200616/LICENSE.txt new file mode 100644 index 00000000..ee7434dc --- /dev/null +++ b/systers_portal/GeoLite2-City_20200616/LICENSE.txt @@ -0,0 +1,3 @@ +Use of this MaxMind product is governed by MaxMind's GeoLite2 End User License Agreement, which can be viewed at https://www.maxmind.com/en/geolite2/eula. + +This database incorporates GeoNames [https://www.geonames.org] geographical data, which is made available under the Creative Commons Attribution 4.0 License. To view a copy of this license, visit https://creativecommons.org/licenses/by/4.0/. diff --git a/systers_portal/GeoLite2-City_20200616/README.txt b/systers_portal/GeoLite2-City_20200616/README.txt new file mode 100644 index 00000000..16e29adb --- /dev/null +++ b/systers_portal/GeoLite2-City_20200616/README.txt @@ -0,0 +1 @@ +Latitude and longitude are not precise and should not be used to identify a particular street address or household. diff --git a/systers_portal/blog/migrations/0001_initial.py b/systers_portal/blog/migrations/0001_initial.py index f63c42bc..f437062e 100644 --- a/systers_portal/blog/migrations/0001_initial.py +++ b/systers_portal/blog/migrations/0001_initial.py @@ -1,91 +1,58 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals +# Generated by Django 3.0.8 on 2020-07-24 20:45 -from django.db import models, migrations +import ckeditor.fields +from django.db import migrations, models class Migration(migrations.Migration): + initial = True + dependencies = [ - ('community', '0001_initial'), - ('users', '0001_squashed_0003_auto_20160207_1550'), ] operations = [ migrations.CreateModel( name='News', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('slug', models.SlugField(unique=True, max_length=150, verbose_name=b'Slug')), - ('title', models.CharField(max_length=255, verbose_name=b'Title')), - ('date_created', models.DateField(auto_now_add=True, verbose_name=b'Date published')), - ('date_modified', models.DateField(auto_now=True, verbose_name=b'Date last modified')), - ('content', models.TextField(verbose_name=b'Content')), - ('is_public', models.BooleanField(default=True, verbose_name=b'Is public')), - ('is_monitored', models.BooleanField(default=False, verbose_name=b'Is monitored')), - ('author', models.ForeignKey(verbose_name=b'Author', to='users.SystersUser')), - ('community', models.ForeignKey(verbose_name=b'Community', to='community.Community')), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('slug', models.SlugField(max_length=150, verbose_name='Slug')), + ('title', models.CharField(max_length=255, verbose_name='Title')), + ('date_created', models.DateField(auto_now_add=True, verbose_name='Date published')), + ('date_modified', models.DateField(auto_now=True, verbose_name='Date last modified')), + ('content', ckeditor.fields.RichTextField(verbose_name='Content')), + ('is_public', models.BooleanField(default=True, verbose_name='Is public')), + ('is_monitored', models.BooleanField(default=False, verbose_name='Is monitored')), ], options={ 'verbose_name_plural': 'News', }, - bases=(models.Model,), ), migrations.CreateModel( name='Resource', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('slug', models.SlugField(unique=True, max_length=150, verbose_name=b'Slug')), - ('title', models.CharField(max_length=255, verbose_name=b'Title')), - ('date_created', models.DateField(auto_now_add=True, verbose_name=b'Date published')), - ('date_modified', models.DateField(auto_now=True, verbose_name=b'Date last modified')), - ('content', models.TextField(verbose_name=b'Content')), - ('is_public', models.BooleanField(default=True, verbose_name=b'Is public')), - ('is_monitored', models.BooleanField(default=False, verbose_name=b'Is monitored')), - ('author', models.ForeignKey(verbose_name=b'Author', to='users.SystersUser')), - ('community', models.ForeignKey(verbose_name=b'Community', to='community.Community')), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('slug', models.SlugField(max_length=150, verbose_name='Slug')), + ('title', models.CharField(max_length=255, verbose_name='Title')), + ('date_created', models.DateField(auto_now_add=True, verbose_name='Date published')), + ('date_modified', models.DateField(auto_now=True, verbose_name='Date last modified')), + ('content', ckeditor.fields.RichTextField(verbose_name='Content')), + ('is_public', models.BooleanField(default=True, verbose_name='Is public')), + ('is_monitored', models.BooleanField(default=False, verbose_name='Is monitored')), ], - options={ - 'abstract': False, - }, - bases=(models.Model,), ), migrations.CreateModel( name='ResourceType', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=255)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True)), ], - options={ - }, - bases=(models.Model,), ), migrations.CreateModel( name='Tag', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=255)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True)), ], - options={ - }, - bases=(models.Model,), - ), - migrations.AddField( - model_name='resource', - name='resource_type', - field=models.ForeignKey(verbose_name=b'Resource type', blank=True, to='blog.ResourceType', null=True), - preserve_default=True, - ), - migrations.AddField( - model_name='resource', - name='tags', - field=models.ManyToManyField(to='blog.Tag', null=True, verbose_name=b'Tags', blank=True), - preserve_default=True, - ), - migrations.AddField( - model_name='news', - name='tags', - field=models.ManyToManyField(to='blog.Tag', null=True, verbose_name=b'Tags', blank=True), - preserve_default=True, ), ] diff --git a/systers_portal/blog/migrations/0002_auto_20140928_2034.py b/systers_portal/blog/migrations/0002_auto_20140928_2034.py deleted file mode 100644 index 4d4b485a..00000000 --- a/systers_portal/blog/migrations/0002_auto_20140928_2034.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import ckeditor.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('blog', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='news', - name='content', - field=ckeditor.fields.RichTextField(verbose_name=b'Content'), - ), - migrations.AlterField( - model_name='resource', - name='content', - field=ckeditor.fields.RichTextField(verbose_name=b'Content'), - ), - ] diff --git a/systers_portal/blog/migrations/0002_auto_20200724_2045.py b/systers_portal/blog/migrations/0002_auto_20200724_2045.py new file mode 100644 index 00000000..3e24069e --- /dev/null +++ b/systers_portal/blog/migrations/0002_auto_20200724_2045.py @@ -0,0 +1,61 @@ +# Generated by Django 3.0.8 on 2020-07-24 20:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('blog', '0001_initial'), + ('users', '0001_initial'), + ('community', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='resource', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Author'), + ), + migrations.AddField( + model_name='resource', + name='community', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.Community', verbose_name='Community'), + ), + migrations.AddField( + model_name='resource', + name='resource_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='blog.ResourceType', verbose_name='Resource type'), + ), + migrations.AddField( + model_name='resource', + name='tags', + field=models.ManyToManyField(blank=True, to='blog.Tag', verbose_name='Tags'), + ), + migrations.AddField( + model_name='news', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Author'), + ), + migrations.AddField( + model_name='news', + name='community', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.Community', verbose_name='Community'), + ), + migrations.AddField( + model_name='news', + name='tags', + field=models.ManyToManyField(blank=True, to='blog.Tag', verbose_name='Tags'), + ), + migrations.AlterUniqueTogether( + name='resource', + unique_together={('community', 'slug')}, + ), + migrations.AlterUniqueTogether( + name='news', + unique_together={('community', 'slug')}, + ), + ] diff --git a/systers_portal/blog/migrations/0003_auto_20150303_0501.py b/systers_portal/blog/migrations/0003_auto_20150303_0501.py deleted file mode 100644 index bb662b19..00000000 --- a/systers_portal/blog/migrations/0003_auto_20150303_0501.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('blog', '0002_auto_20140928_2034'), - ] - - operations = [ - migrations.AlterField( - model_name='resourcetype', - name='name', - field=models.CharField(unique=True, max_length=255), - preserve_default=True, - ), - migrations.AlterField( - model_name='tag', - name='name', - field=models.CharField(unique=True, max_length=255), - preserve_default=True, - ), - ] diff --git a/systers_portal/blog/migrations/0004_auto_20150420_1504.py b/systers_portal/blog/migrations/0004_auto_20150420_1504.py deleted file mode 100644 index 8fe0c8d2..00000000 --- a/systers_portal/blog/migrations/0004_auto_20150420_1504.py +++ /dev/null @@ -1,141 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import ckeditor.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('blog', '0003_auto_20150303_0501'), - ] - - operations = [ - migrations.AlterField( - model_name='news', - name='author', - field=models.ForeignKey(verbose_name='Author', to='users.SystersUser'), - preserve_default=True, - ), - migrations.AlterField( - model_name='news', - name='community', - field=models.ForeignKey(verbose_name='Community', to='community.Community'), - preserve_default=True, - ), - migrations.AlterField( - model_name='news', - name='content', - field=ckeditor.fields.RichTextField(verbose_name='Content'), - preserve_default=True, - ), - migrations.AlterField( - model_name='news', - name='date_created', - field=models.DateField(auto_now_add=True, verbose_name='Date published'), - preserve_default=True, - ), - migrations.AlterField( - model_name='news', - name='date_modified', - field=models.DateField(auto_now=True, verbose_name='Date last modified'), - preserve_default=True, - ), - migrations.AlterField( - model_name='news', - name='is_monitored', - field=models.BooleanField(verbose_name='Is monitored', default=False), - preserve_default=True, - ), - migrations.AlterField( - model_name='news', - name='is_public', - field=models.BooleanField(verbose_name='Is public', default=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='news', - name='slug', - field=models.SlugField(verbose_name='Slug', max_length=150), - preserve_default=True, - ), - migrations.AlterField( - model_name='news', - name='tags', - field=models.ManyToManyField(null=True, blank=True, verbose_name='Tags', to='blog.Tag'), - preserve_default=True, - ), - migrations.AlterField( - model_name='news', - name='title', - field=models.CharField(verbose_name='Title', max_length=255), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='author', - field=models.ForeignKey(verbose_name='Author', to='users.SystersUser'), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='community', - field=models.ForeignKey(verbose_name='Community', to='community.Community'), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='content', - field=ckeditor.fields.RichTextField(verbose_name='Content'), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='date_created', - field=models.DateField(auto_now_add=True, verbose_name='Date published'), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='date_modified', - field=models.DateField(auto_now=True, verbose_name='Date last modified'), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='is_monitored', - field=models.BooleanField(verbose_name='Is monitored', default=False), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='is_public', - field=models.BooleanField(verbose_name='Is public', default=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='resource_type', - field=models.ForeignKey(blank=True, verbose_name='Resource type', to='blog.ResourceType', null=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='slug', - field=models.SlugField(verbose_name='Slug', max_length=150), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='tags', - field=models.ManyToManyField(null=True, blank=True, verbose_name='Tags', to='blog.Tag'), - preserve_default=True, - ), - migrations.AlterField( - model_name='resource', - name='title', - field=models.CharField(verbose_name='Title', max_length=255), - preserve_default=True, - ), - ] diff --git a/systers_portal/blog/migrations/0005_auto_20150522_1138.py b/systers_portal/blog/migrations/0005_auto_20150522_1138.py deleted file mode 100644 index b9fda0d0..00000000 --- a/systers_portal/blog/migrations/0005_auto_20150522_1138.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('blog', '0004_auto_20150420_1504'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='news', - unique_together=set([('community', 'slug')]), - ), - migrations.AlterUniqueTogether( - name='resource', - unique_together=set([('community', 'slug')]), - ), - ] diff --git a/systers_portal/blog/migrations/0006_auto_20150522_1233.py b/systers_portal/blog/migrations/0006_auto_20150522_1233.py deleted file mode 100644 index d4686545..00000000 --- a/systers_portal/blog/migrations/0006_auto_20150522_1233.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('blog', '0005_auto_20150522_1138'), - ] - - operations = [ - migrations.AlterField( - model_name='news', - name='tags', - field=models.ManyToManyField(blank=True, to='blog.Tag', verbose_name='Tags'), - ), - migrations.AlterField( - model_name='resource', - name='tags', - field=models.ManyToManyField(blank=True, to='blog.Tag', verbose_name='Tags'), - ), - ] diff --git a/systers_portal/blog/models.py b/systers_portal/blog/models.py index d28e0297..7ec0272b 100644 --- a/systers_portal/blog/models.py +++ b/systers_portal/blog/models.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import models from common.models import Post @@ -23,7 +23,7 @@ def __str__(self): class News(Post): """Model to represent community news in resource area""" - community = models.ForeignKey(Community, verbose_name="Community") + community = models.ForeignKey(Community, verbose_name="Community", on_delete=models.CASCADE) is_public = models.BooleanField(default=True, verbose_name="Is public") is_monitored = models.BooleanField(default=False, verbose_name="Is monitored") @@ -45,13 +45,13 @@ def get_absolute_url(self): class Resource(Post): """Model to represent community resource in resource area""" - community = models.ForeignKey(Community, verbose_name="Community") + community = models.ForeignKey(Community, verbose_name="Community", on_delete=models.CASCADE) is_public = models.BooleanField(default=True, verbose_name="Is public") is_monitored = models.BooleanField(default=False, verbose_name="Is monitored") tags = models.ManyToManyField(Tag, blank=True, verbose_name="Tags") resource_type = models.ForeignKey(ResourceType, blank=True, null=True, - verbose_name="Resource type") + verbose_name="Resource type", on_delete=models.CASCADE) class Meta: unique_together = ('community', 'slug') diff --git a/systers_portal/blog/tests/test_forms.py b/systers_portal/blog/tests/test_forms.py index 50df816e..a083dec6 100644 --- a/systers_portal/blog/tests/test_forms.py +++ b/systers_portal/blog/tests/test_forms.py @@ -1,3 +1,4 @@ +from cities_light.models import Country, City from django.contrib.auth.models import User from django.test import TestCase @@ -12,8 +13,11 @@ class AddNewsFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_add_news_form(self): @@ -41,8 +45,11 @@ class EditNewsFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_edit_news_form(self): @@ -73,8 +80,11 @@ class AddResourceFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_add_resource_form(self): @@ -102,8 +112,11 @@ class EditResourceFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_edit_news_form(self): @@ -134,8 +147,11 @@ class TagFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_tag_form(self): @@ -160,8 +176,11 @@ class ResourceTypeFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_resourceType_form(self): diff --git a/systers_portal/blog/tests/test_mixins.py b/systers_portal/blog/tests/test_mixins.py index f7c1662d..7913ef75 100644 --- a/systers_portal/blog/tests/test_mixins.py +++ b/systers_portal/blog/tests/test_mixins.py @@ -1,3 +1,4 @@ +from cities_light.models import Country, City from django.contrib.auth.models import User from django.test import TestCase, RequestFactory from django.views.generic import TemplateView @@ -13,8 +14,11 @@ def setUp(self): self.factory = RequestFactory() self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_get_context_data_empty(self): diff --git a/systers_portal/blog/tests/test_models.py b/systers_portal/blog/tests/test_models.py index 574dbf29..605de2bb 100644 --- a/systers_portal/blog/tests/test_models.py +++ b/systers_portal/blog/tests/test_models.py @@ -1,3 +1,4 @@ +from cities_light.models import Country, City from django.test import TestCase from django.contrib.auth.models import User @@ -24,8 +25,11 @@ class NewsModelTestCase(TestCase): def setUp(self): self.user = User.objects.create(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_str(self): @@ -41,8 +45,11 @@ class ResourceModelTestCase(TestCase): def setUp(self): self.user = User.objects.create(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_unicode(self): diff --git a/systers_portal/blog/tests/test_views.py b/systers_portal/blog/tests/test_views.py index 0cba2d3d..ace1d0b1 100644 --- a/systers_portal/blog/tests/test_views.py +++ b/systers_portal/blog/tests/test_views.py @@ -1,5 +1,6 @@ +from cities_light.models import Country, City from django.contrib.auth.models import User, Group -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase, Client from blog.models import News, Resource, ResourceType, Tag @@ -11,8 +12,11 @@ class CommunityNewsListViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) self.client = Client() @@ -71,8 +75,11 @@ class CommunityNewsViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=self.location, admin=self.systers_user) self.client = Client() @@ -100,7 +107,7 @@ def test_multiple_communities_same_slug_news_view(self): two separate communities""" new_community = Community.objects.create(name="Super Unusual Name", slug="bar", - order=2, + order=2, location=self.location, admin=self.systers_user) news1 = News.objects.create(slug="bar", title="Bar", author=self.systers_user, @@ -146,9 +153,13 @@ class AddCommunityNewsViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) + self.client = Client() def test_get_add_community_news(self): @@ -195,8 +206,11 @@ class EditCommunityNewsViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) self.news = News.objects.create(slug="bar", title="Bar", author=self.systers_user, @@ -244,8 +258,11 @@ class DeleteCommunityNewsViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) News.objects.create(slug="bar", title="Bar", author=self.systers_user, @@ -283,8 +300,11 @@ class CommunityResourceListViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) self.client = Client() @@ -367,8 +387,11 @@ class CommunityResourceViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=self.location, admin=self.systers_user) self.client = Client() @@ -396,7 +419,7 @@ def test_multiple_communities_same_slug_resource_view(self): belonging to two separate communities""" new_community = Community.objects.create(name="Super Unusual Name", slug="bar", - order=2, + order=2, location=self.location, admin=self.systers_user) resource1 = Resource.objects.create(slug="bar", title="Bar", author=self.systers_user, @@ -444,9 +467,13 @@ class AddCommunityResourceViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) + self.client = Client() def test_get_add_community_resource(self): @@ -493,8 +520,11 @@ class EditCommunityResourceViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) self.resource = Resource.objects.create(slug="bar", title="Bar", author=self.systers_user, @@ -542,8 +572,11 @@ class DeleteCommunityResourceViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) Resource.objects.create(slug="bar", title="Bar", author=self.systers_user, @@ -581,8 +614,11 @@ class AddTagViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_add_tag_view(self): @@ -607,8 +643,11 @@ class AddResourceTypeViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_add_resourceType_view(self): diff --git a/systers_portal/blog/views.py b/systers_portal/blog/views.py index 2bd03680..4978c90b 100644 --- a/systers_portal/blog/views.py +++ b/systers_portal/blog/views.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from django.shortcuts import get_object_or_404 from django.views.generic import (ListView, DetailView, CreateView, UpdateView, DeleteView) diff --git a/systers_portal/common/migrations/0001_initial.py b/systers_portal/common/migrations/0001_initial.py index b5891d28..628aab0d 100644 --- a/systers_portal/common/migrations/0001_initial.py +++ b/systers_portal/common/migrations/0001_initial.py @@ -1,30 +1,24 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals +# Generated by Django 3.0.8 on 2020-07-24 20:45 -from django.db import models, migrations +from django.db import migrations, models class Migration(migrations.Migration): + initial = True + dependencies = [ - ('users', '0001_squashed_0003_auto_20160207_1550'), - ('contenttypes', '0001_initial'), ] operations = [ migrations.CreateModel( name='Comment', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('date_created', models.DateField(auto_now_add=True, verbose_name=b'Date created')), - ('is_approved', models.BooleanField(default=True, verbose_name=b'Is approved')), - ('body', models.TextField(verbose_name=b'Body')), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date_created', models.DateField(auto_now_add=True, verbose_name='Date created')), + ('is_approved', models.BooleanField(default=True, verbose_name='Is approved')), + ('body', models.TextField(verbose_name='Body')), ('object_id', models.PositiveIntegerField()), - ('author', models.ForeignKey(verbose_name=b'Author', to='users.SystersUser')), - ('content_type', models.ForeignKey(to='contenttypes.ContentType')), ], - options={ - }, - bases=(models.Model,), ), ] diff --git a/systers_portal/common/migrations/0002_auto_20150420_1504.py b/systers_portal/common/migrations/0002_auto_20150420_1504.py deleted file mode 100644 index e58e4984..00000000 --- a/systers_portal/common/migrations/0002_auto_20150420_1504.py +++ /dev/null @@ -1,38 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('common', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='comment', - name='author', - field=models.ForeignKey(verbose_name='Author', to='users.SystersUser'), - preserve_default=True, - ), - migrations.AlterField( - model_name='comment', - name='body', - field=models.TextField(verbose_name='Body'), - preserve_default=True, - ), - migrations.AlterField( - model_name='comment', - name='date_created', - field=models.DateField(auto_now_add=True, verbose_name='Date created'), - preserve_default=True, - ), - migrations.AlterField( - model_name='comment', - name='is_approved', - field=models.BooleanField(verbose_name='Is approved', default=True), - preserve_default=True, - ), - ] diff --git a/systers_portal/common/migrations/0002_auto_20200724_2045.py b/systers_portal/common/migrations/0002_auto_20200724_2045.py new file mode 100644 index 00000000..cc91f43e --- /dev/null +++ b/systers_portal/common/migrations/0002_auto_20200724_2045.py @@ -0,0 +1,28 @@ +# Generated by Django 3.0.8 on 2020-07-24 20:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('users', '0001_initial'), + ('common', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='comment', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Author'), + ), + migrations.AddField( + model_name='comment', + name='content_type', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'), + ), + ] diff --git a/systers_portal/common/models.py b/systers_portal/common/models.py index b53ea10b..dfb17087 100644 --- a/systers_portal/common/models.py +++ b/systers_portal/common/models.py @@ -16,7 +16,7 @@ class Post(models.Model): verbose_name="Date published") date_modified = models.DateField(auto_now=True, auto_now_add=False, verbose_name="Date last modified") - author = models.ForeignKey(SystersUser, verbose_name="Author") + author = models.ForeignKey(SystersUser, verbose_name="Author", on_delete=models.CASCADE) content = RichTextField(verbose_name="Content") class Meta: @@ -28,10 +28,10 @@ class Comment(models.Model): Intended to be used for News and Resource models.""" date_created = models.DateField(auto_now=False, auto_now_add=True, verbose_name="Date created") - author = models.ForeignKey(SystersUser, verbose_name="Author") + author = models.ForeignKey(SystersUser, verbose_name="Author", on_delete=models.CASCADE) is_approved = models.BooleanField(default=True, verbose_name='Is approved') body = models.TextField(verbose_name="Body") - content_type = models.ForeignKey(ContentType) + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() content_object = GenericForeignKey() diff --git a/systers_portal/common/tests/test_mixins.py b/systers_portal/common/tests/test_mixins.py index e8c58d4c..d1c49d5d 100644 --- a/systers_portal/common/tests/test_mixins.py +++ b/systers_portal/common/tests/test_mixins.py @@ -1,3 +1,4 @@ +from cities_light.models import Country, City from django.contrib.auth.models import User, AnonymousUser from django.core.exceptions import ImproperlyConfigured from django.test import TestCase, RequestFactory @@ -13,8 +14,11 @@ def setUp(self): self.factory = RequestFactory() self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_get_context_data_no_community(self): diff --git a/systers_portal/common/tests/test_models.py b/systers_portal/common/tests/test_models.py index 9a9dded5..10db41c2 100644 --- a/systers_portal/common/tests/test_models.py +++ b/systers_portal/common/tests/test_models.py @@ -1,3 +1,4 @@ +from cities_light.models import Country, City from django.test import TestCase from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType @@ -12,8 +13,11 @@ class CommentModelTestCase(TestCase): def setUp(self): self.user = User.objects.create(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_str(self): diff --git a/systers_portal/common/tests/test_views.py b/systers_portal/common/tests/test_views.py index 8b913a64..26040b69 100644 --- a/systers_portal/common/tests/test_views.py +++ b/systers_portal/common/tests/test_views.py @@ -1,4 +1,4 @@ -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase, Client from django.contrib.auth.models import User diff --git a/systers_portal/community/admin.py b/systers_portal/community/admin.py index 3fcb27d7..ad2c4e2a 100644 --- a/systers_portal/community/admin.py +++ b/systers_portal/community/admin.py @@ -13,6 +13,7 @@ def save_model(self, request, obj, form, change): form.cleaned_data['members'] = members super(CommunityAdmin, self).save_model(request, obj, form, change) + admin.site.register(RequestCommunity) admin.site.register(Community, CommunityAdmin) admin.site.register(CommunityPage) diff --git a/systers_portal/community/forms.py b/systers_portal/community/forms.py index 9dc83676..20a34996 100644 --- a/systers_portal/community/forms.py +++ b/systers_portal/community/forms.py @@ -12,9 +12,10 @@ class AddCommunityForm(ModelFormWithHelper): """ Form to create a new Community by admin. """ + class Meta: model = Community - fields = ('name', 'slug', 'order', 'email', 'mailing_list', + fields = ('name', 'slug', 'order', 'location', 'email', 'mailing_list', 'parent_community', 'website', 'facebook', 'googleplus', 'twitter') helper_class = SubmitCancelFormHelper @@ -35,6 +36,7 @@ def save(self, commit=True): class RequestCommunityForm(ModelFormWithHelper): """Form to request a new Community""" + def __init__(self, *args, **kwargs): """Makes some fields required and modifies a field to use widget""" self.user = kwargs.pop('user') @@ -52,7 +54,7 @@ def __init__(self, *args, **kwargs): class Meta: model = RequestCommunity - fields = ('is_member', 'email_id', 'email', 'name', 'slug', 'order', + fields = ('is_member', 'email_id', 'email', 'name', 'slug', 'order', 'location', 'type_community', 'other_community_type', 'parent_community', 'community_channel', 'mailing_list', 'website', 'facebook', 'googleplus', 'twitter', 'social_presence', 'other_account', @@ -96,7 +98,7 @@ def __init__(self, *args, **kwargs): class Meta: model = RequestCommunity - fields = ('is_member', 'email_id', 'email', 'name', 'slug', 'order', + fields = ('is_member', 'email_id', 'email', 'name', 'slug', 'order', 'location', 'type_community', 'other_community_type', 'parent_community', 'community_channel', 'mailing_list', 'website', 'facebook', 'googleplus', 'twitter', 'social_presence', 'other_account', @@ -143,9 +145,10 @@ def clean_order(self): class EditCommunityForm(ModelFormWithHelper): """Form to edit Community profile""" + class Meta: model = Community - fields = ('name', 'slug', 'order', 'email', 'mailing_list', + fields = ('name', 'slug', 'order', 'location', 'email', 'mailing_list', 'parent_community', 'website', 'facebook', 'googleplus', 'twitter') helper_class = SubmitCancelFormHelper @@ -160,6 +163,7 @@ class AddCommunityPageForm(ModelFormWithHelper): * author - currently logged in user, aka the author of the page * community - to which Community the CommunityPage belongs """ + class Meta: model = CommunityPage fields = ('title', 'slug', 'order', 'content') @@ -184,6 +188,7 @@ def save(self, commit=True): class EditCommunityPageForm(ModelFormWithHelper): """Form to edit a CommunityPage.""" + class Meta: model = CommunityPage fields = ('slug', 'title', 'order', 'content') @@ -194,6 +199,7 @@ class Meta: class PermissionGroupsForm(forms.Form): """Form to manage (select/deselect) user permission groups""" + def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') community = kwargs.pop('community') @@ -206,7 +212,7 @@ def __init__(self, *args, **kwargs): name=COMMUNITY_ADMIN.format(community.name)) self.groups.remove(admin_group) choices = [(group.pk, group.name) for group in self.groups] - self.fields['groups'] = forms.\ + self.fields['groups'] = forms. \ MultipleChoiceField(choices=choices, label="", required=False, widget=forms.CheckboxSelectMultiple) self.member_groups = self.user.get_member_groups(self.groups) diff --git a/systers_portal/community/migrations/0001_initial.py b/systers_portal/community/migrations/0001_initial.py index 823e7790..b2bca377 100644 --- a/systers_portal/community/migrations/0001_initial.py +++ b/systers_portal/community/migrations/0001_initial.py @@ -1,36 +1,77 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals +# Generated by Django 3.0.8 on 2020-07-24 20:45 -from django.db import models, migrations +import ckeditor.fields +from django.db import migrations, models class Migration(migrations.Migration): + initial = True + dependencies = [ - ('users', '0001_squashed_0003_auto_20160207_1550'), ] operations = [ migrations.CreateModel( name='Community', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('name', models.CharField(max_length=255, verbose_name=b'Name')), - ('slug', models.SlugField(unique=True, max_length=150, verbose_name=b'Slug')), - ('order', models.IntegerField(unique=True, verbose_name=b'Order')), - ('email', models.EmailField(max_length=255, verbose_name=b'Email', blank=True)), - ('mailing_list', models.EmailField(max_length=255, verbose_name=b'Mailing list', blank=True)), - ('website', models.URLField(max_length=255, verbose_name=b'Website', blank=True)), - ('facebook', models.URLField(max_length=255, verbose_name=b'Facebook', blank=True)), - ('googleplus', models.URLField(max_length=255, verbose_name=b'Google+', blank=True)), - ('twitter', models.URLField(max_length=255, verbose_name=b'Twitter', blank=True)), - ('community_admin', models.ForeignKey(related_name=b'community', verbose_name=b'Community admin', to='users.SystersUser')), - ('members', models.ManyToManyField(related_name=b'communities', null=True, verbose_name=b'Members', to='users.SystersUser', blank=True)), - ('parent_community', models.ForeignKey(verbose_name=b'Parent community', blank=True, to='community.Community', null=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='Name')), + ('slug', models.SlugField(max_length=150, unique=True, verbose_name='Slug')), + ('order', models.IntegerField(unique=True, verbose_name='Order')), + ('email', models.EmailField(blank=True, max_length=255, verbose_name='Email')), + ('mailing_list', models.EmailField(blank=True, max_length=255, verbose_name='Mailing list')), + ('website', models.URLField(blank=True, max_length=255, verbose_name='Website')), + ('facebook', models.URLField(blank=True, max_length=255, verbose_name='Facebook')), + ('googleplus', models.URLField(blank=True, max_length=255, verbose_name='Google+')), + ('twitter', models.URLField(blank=True, max_length=255, verbose_name='Twitter')), ], options={ 'verbose_name_plural': 'Communities', + 'permissions': (('add_community_systersuser', 'Add community Systers User'), ('change_community_systersuser', 'Change community Systers User'), ('delete_community_systersuser', 'Delete community Systers User'), ('add_community_news', 'Add community news'), ('change_community_news', 'Change community news'), ('delete_community_news', 'Delete community news'), ('add_community_resource', 'Add community resource'), ('change_community_resource', 'Change community resource'), ('delete_community_resource', 'Delete community resource'), ('add_community_page', 'Add community page'), ('change_community_page', 'Change community page'), ('delete_community_page', 'Delete community page'), ('approve_community_comment', 'Approve community comment'), ('delete_community_comment', 'Delete community comment'), ('approve_community_joinrequest', 'Approve community join request')), }, - bases=(models.Model,), + ), + migrations.CreateModel( + name='CommunityPage', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('slug', models.SlugField(max_length=150, verbose_name='Slug')), + ('title', models.CharField(max_length=255, verbose_name='Title')), + ('date_created', models.DateField(auto_now_add=True, verbose_name='Date published')), + ('date_modified', models.DateField(auto_now=True, verbose_name='Date last modified')), + ('content', ckeditor.fields.RichTextField(verbose_name='Content')), + ('order', models.IntegerField(verbose_name='Order')), + ], + ), + migrations.CreateModel( + name='RequestCommunity', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, verbose_name='Proposed Community Name')), + ('slug', models.SlugField(max_length=150, unique=True, verbose_name='Slug')), + ('order', models.PositiveIntegerField(blank=True, null=True, verbose_name='Order')), + ('email', models.EmailField(blank=True, max_length=255, verbose_name=' At what email address would you like to be contacted?')), + ('mailing_list', models.EmailField(blank=True, max_length=255, verbose_name='Mailing list of the community')), + ('website', models.URLField(blank=True, max_length=255, verbose_name='Link to the website')), + ('facebook', models.URLField(blank=True, max_length=255, verbose_name='Link to the community on Facebook')), + ('googleplus', models.URLField(blank=True, max_length=255, verbose_name='Link to the community on Google+')), + ('twitter', models.URLField(blank=True, max_length=255, verbose_name='Link to the community on Twitter')), + ('is_member', models.CharField(choices=[('Yes', 'Yes'), ('No', 'No')], default=None, max_length=25, verbose_name='Are you a member of Systers?')), + ('email_id', models.EmailField(blank=True, max_length=255, verbose_name='What email have you used to sign up for Systers?')), + ('type_community', models.CharField(choices=[('Affinity Group', 'Affinity Group (Latinas in Computing, LGBT, etc)'), ('Special Interest Group', 'Special Interest Group (Student Researchers, Systers in Government,Women in Cyber Security, etc) '), ('Email list', 'Email list (using Mailman3)'), ('Other', 'Other')], default=None, max_length=255, verbose_name='Type of Community')), + ('other_community_type', models.CharField(blank=True, max_length=255, verbose_name='Other type of community(Please specify)')), + ('community_channel', models.CharField(choices=[('Existing Social Media Channels ', 'Existing Social Media Channels '), ('Request New Social Media Channels ', 'Request New Social Media Channels ')], default=None, max_length=255, verbose_name='Online Community Channels')), + ('social_presence', models.CharField(max_length=255, null=True, verbose_name='Check off all the social media accounts you can manage for your proposed community:')), + ('other_account', models.CharField(blank=True, max_length=25, verbose_name='Other social channel(Please specify)')), + ('demographic_target_count', models.TextField(blank=True, verbose_name='Who will it serve ( explain target demographics and number of people):')), + ('purpose', models.TextField(blank=True, verbose_name='Explain the purpose and need for this group or account:')), + ('is_avail_volunteer', models.CharField(choices=[('Yes', 'Yes'), ('No', 'No')], default=None, max_length=25, verbose_name='Do you have volunteers committed?')), + ('count_avail_volunteer', models.PositiveIntegerField(default=0, verbose_name='If yes, how many?')), + ('content_developer', models.TextField(blank=True, verbose_name='Explain the content of this group. What service will this group provide (example: discussion, linksharing, support)? Who will develop the content? What kind of content will be shared in the group? How often will moderators post/engage with users?')), + ('selection_criteria', models.TextField(blank=True, verbose_name='Will there be screening of new members of will this group be open to anyone? If there will be screening,what will the criteria for membership be?')), + ('is_real_time', models.TextField(blank=True, verbose_name=' Will there be real-time meetings in addition to an online community? (Example, at the Grace Hopper Celebration; regional meetings; etc)')), + ('is_approved', models.BooleanField(default=False, verbose_name='Approved')), + ('date_created', models.DateTimeField(auto_now_add=True, verbose_name='Date created')), + ], ), ] diff --git a/systers_portal/community/migrations/0002_auto_20200724_2045.py b/systers_portal/community/migrations/0002_auto_20200724_2045.py new file mode 100644 index 00000000..eaebe8c7 --- /dev/null +++ b/systers_portal/community/migrations/0002_auto_20200724_2045.py @@ -0,0 +1,72 @@ +# Generated by Django 3.0.8 on 2020-07-24 20:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('users', '0001_initial'), + ('community', '0001_initial'), + ('cities_light', '0009_add_subregion'), + ] + + operations = [ + migrations.AddField( + model_name='requestcommunity', + name='approved_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Approved by'), + ), + migrations.AddField( + model_name='requestcommunity', + name='location', + field=models.ForeignKey(default='', on_delete=django.db.models.deletion.CASCADE, to='cities_light.City', verbose_name='Location'), + ), + migrations.AddField( + model_name='requestcommunity', + name='parent_community', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='community.Community', verbose_name='Parent community'), + ), + migrations.AddField( + model_name='requestcommunity', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='requestor', to='users.SystersUser', verbose_name='Created by'), + ), + migrations.AddField( + model_name='communitypage', + name='author', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Author'), + ), + migrations.AddField( + model_name='communitypage', + name='community', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.Community', verbose_name='Community'), + ), + migrations.AddField( + model_name='community', + name='admin', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='community', to='users.SystersUser', verbose_name='Community admin'), + ), + migrations.AddField( + model_name='community', + name='location', + field=models.ForeignKey(default='', on_delete=django.db.models.deletion.DO_NOTHING, to='cities_light.City', verbose_name='Location'), + ), + migrations.AddField( + model_name='community', + name='members', + field=models.ManyToManyField(blank=True, related_name='communities', to='users.SystersUser', verbose_name='Members'), + ), + migrations.AddField( + model_name='community', + name='parent_community', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='community.Community', verbose_name='Parent community'), + ), + migrations.AlterUniqueTogether( + name='communitypage', + unique_together={('community', 'order'), ('community', 'slug')}, + ), + ] diff --git a/systers_portal/community/migrations/0002_communitypage.py b/systers_portal/community/migrations/0002_communitypage.py deleted file mode 100644 index 26c54e50..00000000 --- a/systers_portal/community/migrations/0002_communitypage.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0001_squashed_0003_auto_20160207_1550'), - ('community', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='CommunityPage', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('slug', models.SlugField(unique=True, max_length=150, verbose_name=b'Slug')), - ('title', models.CharField(max_length=255, verbose_name=b'Title')), - ('date_created', models.DateField(auto_now_add=True, verbose_name=b'Date published')), - ('date_modified', models.DateField(auto_now=True, verbose_name=b'Date last modified')), - ('content', models.TextField(verbose_name=b'Content')), - ('order', models.IntegerField(unique=True, verbose_name=b'Order')), - ('author', models.ForeignKey(verbose_name=b'Author', to='users.SystersUser')), - ('community', models.ForeignKey(verbose_name=b'Community', to='community.Community')), - ], - options={ - 'abstract': False, - }, - bases=(models.Model,), - ), - ] diff --git a/systers_portal/community/migrations/0003_auto_20140928_2034.py b/systers_portal/community/migrations/0003_auto_20140928_2034.py deleted file mode 100644 index 4f6b0bf4..00000000 --- a/systers_portal/community/migrations/0003_auto_20140928_2034.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import ckeditor.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0002_communitypage'), - ] - - operations = [ - migrations.AlterField( - model_name='communitypage', - name='content', - field=ckeditor.fields.RichTextField(verbose_name=b'Content'), - ), - ] diff --git a/systers_portal/community/migrations/0004_joinrequest.py b/systers_portal/community/migrations/0004_joinrequest.py deleted file mode 100644 index 889eceb2..00000000 --- a/systers_portal/community/migrations/0004_joinrequest.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0001_squashed_0003_auto_20160207_1550'), - ('community', '0003_auto_20140928_2034'), - ] - - operations = [ - migrations.CreateModel( - name='JoinRequest', - fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), - ('date_created', models.DateTimeField(auto_now_add=True)), - ('is_approved', models.BooleanField(default=False)), - ('approved_by', models.ForeignKey(related_name=b'approved_by', blank=True, to='users.SystersUser', null=True)), - ('community', models.ForeignKey(to='community.Community')), - ('user', models.ForeignKey(related_name=b'created_by', to='users.SystersUser')), - ], - options={ - }, - bases=(models.Model,), - ), - ] diff --git a/systers_portal/community/migrations/0005_auto_20141006_2117.py b/systers_portal/community/migrations/0005_auto_20141006_2117.py deleted file mode 100644 index c98b60db..00000000 --- a/systers_portal/community/migrations/0005_auto_20141006_2117.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0004_joinrequest'), - ] - - operations = [ - migrations.AlterModelOptions( - name='community', - options={'verbose_name_plural': 'Communities', 'permissions': (('add_community_systersuser', 'Add community Systers User'), ('change_community_systersuser', 'Change community Systers User'), ('delete_community_systersuser', 'Delete community Systers User'), ('add_community_news', 'Add community news'), ('change_community_news', 'Change community news'), ('delete_community_news', 'Delete community news'), ('add_community_resource', 'Add community resource'), ('change_community_resource', 'Change community resource'), ('delete_community_resource', 'Delete community resource'), ('add_community_page', 'Add community page'), ('change_community_page', 'Change community page'), ('delete_community_page', 'Delete community page'), ('approve_community_comment', 'Approve community comment'), ('delete_community_comment', 'Delete community comment'), ('approve_community_joinrequest', 'Approve community join request'))}, - ), - ] diff --git a/systers_portal/community/migrations/0006_auto_20150208_0818.py b/systers_portal/community/migrations/0006_auto_20150208_0818.py deleted file mode 100644 index 20149d08..00000000 --- a/systers_portal/community/migrations/0006_auto_20150208_0818.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0005_auto_20141006_2117'), - ] - - operations = [ - migrations.RemoveField( - model_name='joinrequest', - name='approved_by', - ), - migrations.RemoveField( - model_name='joinrequest', - name='community', - ), - migrations.RemoveField( - model_name='joinrequest', - name='user', - ), - migrations.DeleteModel( - name='JoinRequest', - ), - ] diff --git a/systers_portal/community/migrations/0007_auto_20150227_0728.py b/systers_portal/community/migrations/0007_auto_20150227_0728.py deleted file mode 100644 index f20a7b88..00000000 --- a/systers_portal/community/migrations/0007_auto_20150227_0728.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0006_auto_20150208_0818'), - ] - - operations = [ - migrations.RenameField( - model_name='community', - old_name='community_admin', - new_name='admin', - ), - ] diff --git a/systers_portal/community/migrations/0008_auto_20150420_1504.py b/systers_portal/community/migrations/0008_auto_20150420_1504.py deleted file mode 100644 index 121dc158..00000000 --- a/systers_portal/community/migrations/0008_auto_20150420_1504.py +++ /dev/null @@ -1,135 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations -import ckeditor.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0007_auto_20150227_0728'), - ] - - operations = [ - migrations.AlterField( - model_name='community', - name='admin', - field=models.ForeignKey(verbose_name='Community admin', to='users.SystersUser', related_name='community'), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='email', - field=models.EmailField(blank=True, verbose_name='Email', max_length=255), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='facebook', - field=models.URLField(blank=True, verbose_name='Facebook', max_length=255), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='googleplus', - field=models.URLField(blank=True, verbose_name='Google+', max_length=255), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='mailing_list', - field=models.EmailField(blank=True, verbose_name='Mailing list', max_length=255), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='members', - field=models.ManyToManyField(null=True, blank=True, verbose_name='Members', to='users.SystersUser', related_name='communities'), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='name', - field=models.CharField(verbose_name='Name', max_length=255), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='order', - field=models.IntegerField(unique=True, verbose_name='Order'), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='parent_community', - field=models.ForeignKey(blank=True, verbose_name='Parent community', to='community.Community', null=True), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='slug', - field=models.SlugField(unique=True, verbose_name='Slug', max_length=150), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='twitter', - field=models.URLField(blank=True, verbose_name='Twitter', max_length=255), - preserve_default=True, - ), - migrations.AlterField( - model_name='community', - name='website', - field=models.URLField(blank=True, verbose_name='Website', max_length=255), - preserve_default=True, - ), - migrations.AlterField( - model_name='communitypage', - name='author', - field=models.ForeignKey(verbose_name='Author', to='users.SystersUser'), - preserve_default=True, - ), - migrations.AlterField( - model_name='communitypage', - name='community', - field=models.ForeignKey(verbose_name='Community', to='community.Community'), - preserve_default=True, - ), - migrations.AlterField( - model_name='communitypage', - name='content', - field=ckeditor.fields.RichTextField(verbose_name='Content'), - preserve_default=True, - ), - migrations.AlterField( - model_name='communitypage', - name='date_created', - field=models.DateField(auto_now_add=True, verbose_name='Date published'), - preserve_default=True, - ), - migrations.AlterField( - model_name='communitypage', - name='date_modified', - field=models.DateField(auto_now=True, verbose_name='Date last modified'), - preserve_default=True, - ), - migrations.AlterField( - model_name='communitypage', - name='order', - field=models.IntegerField(unique=True, verbose_name='Order'), - preserve_default=True, - ), - migrations.AlterField( - model_name='communitypage', - name='slug', - field=models.SlugField(verbose_name='Slug', max_length=150), - preserve_default=True, - ), - migrations.AlterField( - model_name='communitypage', - name='title', - field=models.CharField(verbose_name='Title', max_length=255), - preserve_default=True, - ), - ] diff --git a/systers_portal/community/migrations/0009_auto_20150420_1536.py b/systers_portal/community/migrations/0009_auto_20150420_1536.py deleted file mode 100644 index 5e606c04..00000000 --- a/systers_portal/community/migrations/0009_auto_20150420_1536.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0008_auto_20150420_1504'), - ] - - operations = [ - migrations.AlterField( - model_name='communitypage', - name='order', - field=models.IntegerField(verbose_name='Order'), - preserve_default=True, - ), - ] diff --git a/systers_portal/community/migrations/0010_auto_20150522_1138.py b/systers_portal/community/migrations/0010_auto_20150522_1138.py deleted file mode 100644 index 5c0425cf..00000000 --- a/systers_portal/community/migrations/0010_auto_20150522_1138.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0009_auto_20150420_1536'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='communitypage', - unique_together=set([('community', 'slug'), ('community', 'order')]), - ), - ] diff --git a/systers_portal/community/migrations/0011_auto_20150522_1233.py b/systers_portal/community/migrations/0011_auto_20150522_1233.py deleted file mode 100644 index 64b54744..00000000 --- a/systers_portal/community/migrations/0011_auto_20150522_1233.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import models, migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0010_auto_20150522_1138'), - ] - - operations = [ - migrations.AlterField( - model_name='community', - name='members', - field=models.ManyToManyField(blank=True, related_name='communities', to='users.SystersUser', verbose_name='Members'), - ), - ] diff --git a/systers_portal/community/migrations/0012_requestcommunity.py b/systers_portal/community/migrations/0012_requestcommunity.py deleted file mode 100644 index a94bfec8..00000000 --- a/systers_portal/community/migrations/0012_requestcommunity.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-03-09 12:17 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('users', '0001_squashed_0003_auto_20160207_1550'), - ('community', '0011_auto_20150522_1233'), - ] - - operations = [ - migrations.CreateModel( - name='RequestCommunity', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255, verbose_name='Proposed Community Name')), - ('slug', models.SlugField(max_length=150, unique=True, verbose_name='Slug')), - ('order', models.PositiveIntegerField(blank=True, null=True, verbose_name='Order')), - ('email', models.EmailField(blank=True, max_length=255, verbose_name=' At what email address would you like to be contacted?')), - ('mailing_list', models.EmailField(blank=True, max_length=255, verbose_name='Mailing list of the community')), - ('website', models.URLField(blank=True, max_length=255, verbose_name='Link to the website')), - ('facebook', models.URLField(blank=True, max_length=255, verbose_name='Link to the community on Facebook')), - ('googleplus', models.URLField(blank=True, max_length=255, verbose_name='Link to the community on Google+')), - ('twitter', models.URLField(blank=True, max_length=255, verbose_name='Link to the community on Twitter')), - ('is_member', models.CharField(choices=[('Yes', 'Yes'), ('No', 'No')], default=None, max_length=25, verbose_name='Are you a member of Systers?')), - ('email_id', models.EmailField(blank=True, max_length=255, verbose_name='What email have you used to sign up for Systers?')), - ('type_community', models.CharField(choices=[('Affinity Group', 'Affinity Group (Latinas in Computing, LGBT, etc'), ('Special Interest Group', 'Special Interest Group (Student Researchers, Systers in Government,Women in Cyber Security, etc) '), ('Email list', 'Email list (using Mailman3)'), ('Other', 'Other')], default=None, max_length=255, verbose_name='Type of Community')), - ('other_community_type', models.CharField(blank=True, max_length=255, verbose_name='Other type of community(Please specify)')), - ('community_channel', models.CharField(choices=[('Existing Social Media Channels ', 'Existing Social Media Channels '), ('Request New Social Media Channels ', 'Request New Social Media Channels ')], default=None, max_length=255, verbose_name='Online Community Channels')), - ('social_presence', models.CharField(max_length=255, null=True, verbose_name='Check off all the social media accounts you can manage for your proposed community:')), - ('other_account', models.CharField(blank=True, max_length=25, verbose_name='Other social channel(Please specify)')), - ('demographic_target_count', models.TextField(blank=True, verbose_name='Who will it serve ( explain target demographics and number of people):')), - ('purpose', models.TextField(blank=True, verbose_name='Explain the purpose and need for this group or account:')), - ('is_avail_volunteer', models.CharField(choices=[('Yes', 'Yes'), ('No', 'No')], default=None, max_length=25, verbose_name='Do you have volunteers committed?')), - ('count_avail_volunteer', models.PositiveIntegerField(default=0, verbose_name='If yes, how many?')), - ('content_developer', models.TextField(blank=True, verbose_name='Explain the content of this group. What service will this group provide (example: discussion, linksharing, support)? Who will develop the content? What kind of content will be shared in the group? How often will moderators post/engage with users?')), - ('selection_criteria', models.TextField(blank=True, verbose_name='Will there be screening of new members of will this group be open to anyone? If there will be screening,what will the criteria for membership be?')), - ('is_real_time', models.TextField(blank=True, verbose_name=' Will there be real-time meetings in addition to an online community? (Example, at the Grace Hopper Celebration; regional meetings; etc)')), - ('is_approved', models.BooleanField(default=False, verbose_name='Approved')), - ('date_created', models.DateTimeField(auto_now_add=True, verbose_name='Date created')), - ('approved_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Approved by')), - ('parent_community', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='community.Community', verbose_name='Parent community')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='requestor', to='users.SystersUser', verbose_name='Created by')), - ], - ), - ] diff --git a/systers_portal/community/migrations/0013_auto_20200316_1806.py b/systers_portal/community/migrations/0013_auto_20200316_1806.py deleted file mode 100644 index ec8e9dd7..00000000 --- a/systers_portal/community/migrations/0013_auto_20200316_1806.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2020-03-16 18:06 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0012_requestcommunity'), - ] - - operations = [ - migrations.AlterField( - model_name='requestcommunity', - name='type_community', - field=models.CharField(choices=[('Affinity Group', 'Affinity Group (Latinas in Computing, LGBT, etc)'), ('Special Interest Group', 'Special Interest Group (Student Researchers, Systers in Government,Women in Cyber Security, etc) '), ('Email list', 'Email list (using Mailman3)'), ('Other', 'Other')], default=None, max_length=255, verbose_name='Type of Community'), - ), - ] diff --git a/systers_portal/community/migrations/0013_auto_20200403_1757.py b/systers_portal/community/migrations/0013_auto_20200403_1757.py deleted file mode 100644 index 058d7334..00000000 --- a/systers_portal/community/migrations/0013_auto_20200403_1757.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2020-04-03 17:57 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0012_requestcommunity'), - ] - - operations = [ - migrations.AlterField( - model_name='requestcommunity', - name='type_community', - field=models.CharField(choices=[('Affinity Group', 'Affinity Group (Latinas in Computing, LGBT, etc)'), ('Special Interest Group', 'Special Interest Group (Student Researchers, Systers in Government,Women in Cyber Security, etc) '), ('Email list', 'Email list (using Mailman3)'), ('Other', 'Other')], default=None, max_length=255, verbose_name='Type of Community'), - ), - ] diff --git a/systers_portal/community/migrations/0014_auto_20200324_1252.py b/systers_portal/community/migrations/0014_auto_20200324_1252.py deleted file mode 100644 index 4feb2025..00000000 --- a/systers_portal/community/migrations/0014_auto_20200324_1252.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2020-03-24 12:52 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0013_auto_20200316_1806'), - ] - - operations = [ - migrations.AlterField( - model_name='requestcommunity', - name='type_community', - field=models.CharField(choices=[('Affinity Group', 'Affinity Group (Latinas in Computing, LGBT, etc'), ('Special Interest Group', 'Special Interest Group (Student Researchers, Systers in Government,Women in Cyber Security, etc) '), ('Email list', 'Email list (using Mailman3)'), ('Other', 'Other')], default=None, max_length=255, verbose_name='Type of Community'), - ), - ] diff --git a/systers_portal/community/migrations/0015_merge_20200404_0832.py b/systers_portal/community/migrations/0015_merge_20200404_0832.py deleted file mode 100644 index 57373a97..00000000 --- a/systers_portal/community/migrations/0015_merge_20200404_0832.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2020-04-04 08:32 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('community', '0013_auto_20200403_1757'), - ('community', '0014_auto_20200324_1252'), - ] - - operations = [ - ] diff --git a/systers_portal/community/models.py b/systers_portal/community/models.py index 28774ee8..3a7d83bf 100644 --- a/systers_portal/community/models.py +++ b/systers_portal/community/models.py @@ -1,5 +1,5 @@ from django.contrib.auth.models import Group -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db import models from common.models import Post @@ -8,6 +8,7 @@ YES_NO_CHOICES) from membership.constants import NOT_MEMBER, OK from users.models import SystersUser +from cities_light.models import City class Community(models.Model): @@ -15,6 +16,8 @@ class Community(models.Model): name = models.CharField(max_length=255, verbose_name="Name") slug = models.SlugField(max_length=150, unique=True, verbose_name="Slug") order = models.IntegerField(unique=True, verbose_name="Order") + location = models.ForeignKey(City, verbose_name="Location", default="", + on_delete=models.DO_NOTHING) email = models.EmailField(max_length=255, blank=True, verbose_name="Email") mailing_list = models.EmailField(max_length=255, blank=True, verbose_name="Mailing list") @@ -22,9 +25,9 @@ class Community(models.Model): related_name='communities', verbose_name="Members") admin = models.ForeignKey(SystersUser, related_name='community', - verbose_name="Community admin") + verbose_name="Community admin", on_delete=models.CASCADE) parent_community = models.ForeignKey('self', blank=True, null=True, - verbose_name="Parent community") + verbose_name="Parent community", on_delete=models.CASCADE) website = models.URLField(max_length=255, blank=True, verbose_name="Website") facebook = models.URLField(max_length=255, blank=True, @@ -80,28 +83,24 @@ def get_absolute_url(self): def has_changed_name(self): """Check if community has a new name - :return: True if community changed name, False otherwise """ return self.name != self.original_name def has_changed_admin(self): """Check if community has a new admin - :return: True if community changed admin, False otherwise """ return self.admin != self.original_admin def add_member(self, systers_user): """Add community member - :param systers_user: SystersUser objects """ self.members.add(systers_user) def remove_member(self, systers_user): """Remove community member - :param systers_user: SystersUser object :return: """ @@ -109,7 +108,6 @@ def remove_member(self, systers_user): def get_fields(self): """Get model fields of a Community object - :return: list of tuples (fieldname, fieldvalue) """ return [(field.name, getattr(self, field.name)) for field in @@ -117,7 +115,6 @@ def get_fields(self): def set_new_admin(self, new_admin): """Transfer the admin role from the old to the new admin - :param new_admin: SystersUser object new admin of the community :return: OK if setting was successful, NOT_MEMBER if settings was unsuccessful, since the new admin is not a member of the @@ -141,12 +138,14 @@ class RequestCommunity(models.Model): slug = models.SlugField(max_length=150, unique=True, verbose_name="Slug") order = models.PositiveIntegerField( null=True, blank=True, verbose_name="Order") + location = models.ForeignKey(City, verbose_name="Location", + default="", on_delete=models.CASCADE) email = models.EmailField(max_length=255, blank=True, verbose_name=" At what email address would you like to be contacted?") mailing_list = models.EmailField(max_length=255, blank=True, verbose_name="Mailing list of the community") parent_community = models.ForeignKey(Community, blank=True, null=True, - verbose_name="Parent community") + verbose_name="Parent community", on_delete=models.CASCADE) website = models.URLField(max_length=255, blank=True, verbose_name="Link to the website") facebook = models.URLField(max_length=255, blank=True, @@ -193,10 +192,10 @@ class RequestCommunity(models.Model): verbose_name=" Will there be real-time meetings in addition to an online community?\ (Example, at the Grace Hopper Celebration; regional meetings; etc)") user = models.ForeignKey( - SystersUser, verbose_name="Created by", related_name="requestor") + SystersUser, verbose_name="Created by", related_name="requestor", on_delete=models.CASCADE) is_approved = models.BooleanField(default=False, verbose_name="Approved") approved_by = models.ForeignKey(SystersUser, blank=True, null=True, - verbose_name='Approved by') + verbose_name='Approved by', on_delete=models.CASCADE) date_created = models.DateTimeField( auto_now_add=True, verbose_name="Date created") @@ -205,7 +204,6 @@ def __str__(self): def get_fields(self): """Get model fields of a RequestCommunity object - :return: list of tuples (fieldname, fieldvalue) """ return [(field.name, getattr(self, field.name)) for field in @@ -213,7 +211,6 @@ def get_fields(self): def get_verbose_fields(self): """Get verbose names of RequestCommunity object's model fields - :return: list of tuples (verbosefieldname, fieldvalue) """ @@ -224,7 +221,7 @@ def get_verbose_fields(self): class CommunityPage(Post): """Model to represent an arbitrary community page""" order = models.IntegerField(verbose_name="Order") - community = models.ForeignKey(Community, verbose_name="Community") + community = models.ForeignKey(Community, verbose_name="Community", on_delete=models.CASCADE) class Meta: unique_together = (('community', 'slug'), ('community', 'order')) diff --git a/systers_portal/community/tests/test_context_processors.py b/systers_portal/community/tests/test_context_processors.py deleted file mode 100644 index d3a7ba1f..00000000 --- a/systers_portal/community/tests/test_context_processors.py +++ /dev/null @@ -1,26 +0,0 @@ -from django.contrib.auth.models import User -from django.core.urlresolvers import reverse -from django.test import TestCase, Client - -from users.models import SystersUser -from community.models import Community - - -class CommunitiesProcessorTestCase(TestCase): - def setUp(self): - self.user = User.objects.create(username='foo', password='foobar') - self.systers_user = SystersUser.objects.get(user=self.user) - self.client = Client() - - def test_communities_processor(self): - """Test the rendering of all communities in the templates""" - Community.objects.create(name="Foo", slug="foo", order=1, - admin=self.systers_user) - Community.objects.create(name="Boo", slug="boo", order=2, - admin=self.systers_user) - index_url = reverse('index') - response = self.client.get(index_url) - self.assertContains(response, 'Foo') - self.assertContains(response, 'Boo') diff --git a/systers_portal/community/tests/test_forms.py b/systers_portal/community/tests/test_forms.py index 3cee68ce..b7b99e38 100644 --- a/systers_portal/community/tests/test_forms.py +++ b/systers_portal/community/tests/test_forms.py @@ -1,7 +1,7 @@ +from cities_light.models import City, Country from django.contrib.auth.models import User, Group from django.test import TestCase - from community.forms import (EditCommunityForm, AddCommunityPageForm, EditCommunityPageForm, PermissionGroupsForm, RequestCommunityForm, EditCommunityRequestForm, @@ -14,6 +14,9 @@ class RequestCommunityFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) def test_request_community_form(self): """Test Requestcommunity form""" @@ -21,7 +24,8 @@ def test_request_community_form(self): 'slug': 'foo'} form = RequestCommunityForm(data=invalid_data, user=self.user) self.assertFalse(form.is_valid()) - valid_data = {'name': 'Bar', 'slug': 'bar', 'order': '1', + + valid_data = {'name': 'Bar', 'slug': 'bar', 'order': '1', 'location': self.location.id, 'is_member': 'Yes', 'email': 'foo@bar.com', 'type_community': 'Other', 'community_channel': 'Existing Social Media Channels ', 'demographic_target_count': 'Foobarbar', 'purpose': 'foopurpose', @@ -35,6 +39,7 @@ def test_request_community_form(self): self.community_request = RequestCommunity.objects.get() self.assertEqual(self.community_request.name, 'Bar') self.assertEqual(self.community_request.slug, 'bar') + self.assertEqual(self.community_request.location, self.location) self.assertEqual(self.community_request.user, self.systers_user) @@ -42,9 +47,12 @@ class EditCommunityRequestFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community_request = RequestCommunity.objects.create( - name="Foo", slug="foo", order=1, is_member='Yes', type_community='Other', - community_channel='Existing Social Media Channels ', + name="Foo", slug="foo", order=1, location=self.location, is_member='Yes', + type_community='Other', community_channel='Existing Social Media Channels ', is_avail_volunteer='Yes', count_avail_volunteer=0, user=self.systers_user) @@ -66,7 +74,7 @@ def test_edit_community_form(self): form = EditCommunityRequestForm( data=order_none_data, instance=self.community_request) self.assertFalse(form.is_valid()) - data = {'name': 'Bar', 'slug': 'bar', 'order': '1', + data = {'name': 'Bar', 'slug': 'bar', 'order': '1', 'location': self.location.id, 'is_member': 'Yes', 'email': 'foo@bar.com', 'type_community': 'Other', 'community_channel': 'Existing Social Media Channels ', 'demographic_target_count': 'Foobarbar', 'purpose': 'foopurpose', @@ -82,14 +90,14 @@ def test_edit_community_form(self): self.assertEqual(self.community_request.slug, 'bar') # Test if order of the request exists in Community self.community = Community.objects.create(name="FooBarComm", slug="foobar", - order=1, + order=1, location=self.location, admin=self.systers_user) form = EditCommunityRequestForm( data=data, instance=self.community_request) self.assertFalse(form.is_valid()) # Test if slug of the request exists in Community self.community = Community.objects.create(name="FooBarComm", slug="bar", - order=2, + order=2, location=self.location, admin=self.systers_user) form = EditCommunityRequestForm( data=data, instance=self.community_request) @@ -100,8 +108,11 @@ class EditCommunityFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=self.location, admin=self.systers_user) def test_edit_community_form(self): @@ -109,6 +120,7 @@ def test_edit_community_form(self): data = {'name': 'Bar', 'slug': 'bar', 'order': 1, + 'location': self.location.id, 'admin': self.systers_user} form = EditCommunityForm(data=data, instance=self.community) self.assertTrue(form.is_valid()) @@ -121,6 +133,9 @@ class AddCommunityFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) def test_add_community_form(self): """Test add Community Form""" @@ -131,7 +146,8 @@ def test_add_community_form(self): data = {'name': 'Bar', 'slug': 'foo', - 'order': '1'} + 'order': '1', + 'location': self.location.id} form = AddCommunityForm(data=data, admin=self.systers_user) self.assertTrue(form.is_valid()) form.save() @@ -145,8 +161,11 @@ class AddCommunityPageFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_add_community_page_form(self): @@ -173,8 +192,11 @@ class EditCommunityPageFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_edit_community_page_form(self): @@ -205,8 +227,11 @@ class PermissionGroupsFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_permissions_groups_form(self): diff --git a/systers_portal/community/tests/test_mixins.py b/systers_portal/community/tests/test_mixins.py index f315dbed..cd59543b 100644 --- a/systers_portal/community/tests/test_mixins.py +++ b/systers_portal/community/tests/test_mixins.py @@ -1,3 +1,4 @@ +from cities_light.models import Country, City from django.contrib.auth.models import User from django.core.exceptions import ImproperlyConfigured from django.test import TestCase @@ -12,8 +13,11 @@ class CommunityMenuMixinTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_get_context_data_no_community(self): diff --git a/systers_portal/community/tests/test_models.py b/systers_portal/community/tests/test_models.py index acba78ed..3104fcfb 100644 --- a/systers_portal/community/tests/test_models.py +++ b/systers_portal/community/tests/test_models.py @@ -1,3 +1,4 @@ +from cities_light.models import City, Country from django.contrib.auth.models import User, Group from django.db.models.signals import post_save, post_delete from django.test import TestCase @@ -12,9 +13,12 @@ class RequestCommunityModelTestCase(TestCase): def setUp(self): self.user = User.objects.create(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.request_community = RequestCommunity.objects.create( name="Foo", slug="foo", order=1, is_member='Yes', type_community='Other', - community_channel='Existing Social Media Channels ', + location=location, community_channel='Existing Social Media Channels ', is_avail_volunteer='Yes', count_avail_volunteer=0, user=self.systers_user) @@ -43,8 +47,11 @@ def setUp(self): dispatch_uid="remove_groups") self.user = User.objects.create(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=self.location, admin=self.systers_user) def test_str(self): @@ -104,7 +111,7 @@ def test_set_new_admin(self): post_delete.connect(remove_community_groups, sender=Community, dispatch_uid="remove_groups") community = Community.objects.create(name="Bar", slug="bar", - order=2, + order=2, location=self.location, admin=self.systers_user) user = User.objects.create(username='bar', password='foobar') bar_systers_user = SystersUser.objects.get(user=user) @@ -126,8 +133,11 @@ class CommunityPageModelTestCase(TestCase): def setUp(self): self.user = User.objects.create(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_str(self): diff --git a/systers_portal/community/tests/test_signals.py b/systers_portal/community/tests/test_signals.py index 59996b4b..d56fc951 100644 --- a/systers_portal/community/tests/test_signals.py +++ b/systers_portal/community/tests/test_signals.py @@ -1,3 +1,4 @@ +from cities_light.models import City, Country from django.test import TestCase from django.contrib.auth.models import Group, User from django.db.models.signals import post_save, post_delete @@ -20,8 +21,12 @@ def test_manage_community_groups(self): object""" user1 = User.objects.create(username='foo', password='foobar') systers_user = SystersUser.objects.get(user=user1) - community = Community.objects.create(name="Foo", slug="foo", order=1, - admin=systers_user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) + community = Community.objects.create(name="Foo", slug="foo", + order=1, location=location, + admin=systers_user) groups_count = Group.objects.count() self.assertEqual(groups_count, 4) community_admin_group = Group.objects.get( @@ -51,8 +56,12 @@ def test_remove_community_groups(self): """Test the removal of groups when a community is deleted""" self.user = User.objects.create(username='foo', password='foobar') systers_user = SystersUser.objects.get(user=self.user) - community = Community.objects.create(name="Foo", slug="foo", order=1, - admin=systers_user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) + community = Community.objects.create(name="Foo", slug="foo", + order=1, location=location, + admin=systers_user) groups_count = Group.objects.count() self.assertEqual(groups_count, 4) community.delete() diff --git a/systers_portal/community/tests/test_utils.py b/systers_portal/community/tests/test_utils.py index cbd7efea..c2d1a460 100644 --- a/systers_portal/community/tests/test_utils.py +++ b/systers_portal/community/tests/test_utils.py @@ -1,3 +1,4 @@ +from cities_light.models import Country, City from django.test import TestCase from django.contrib.auth.models import Group, User from guardian.shortcuts import get_perms @@ -69,8 +70,12 @@ def test_assign_permissions(self): """Test assignment of permissions to community""" self.user = User.objects.create(username='foo', password='foobar') systers_user = SystersUser.objects.get(user=self.user) - community = Community.objects.create(name="Foo", slug="foo", order=1, - admin=systers_user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) + community = Community.objects.create(name="Foo", slug="foo", + order=1, location=location, + admin=systers_user) name = community.name groups = create_groups(name, groups_templates) assign_permissions(community, groups, diff --git a/systers_portal/community/tests/test_views.py b/systers_portal/community/tests/test_views.py index 330ad96f..e5791fbb 100644 --- a/systers_portal/community/tests/test_views.py +++ b/systers_portal/community/tests/test_views.py @@ -1,5 +1,6 @@ +from cities_light.models import City, Country from django.contrib.auth.models import User, Group -from django.core.urlresolvers import reverse +from django.urls import reverse from django.db.models.signals import post_save, post_delete from django.test import TestCase @@ -14,6 +15,9 @@ class RequestCommunityViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) def test_get_request_community_view(self): url = reverse('request_community') @@ -42,7 +46,8 @@ def test_post_request_community_view(self): # Test with login but valid data self.client.login(username='foo', password='foobar') valid_data = {'name': 'Bar', 'slug': 'foo', 'order': '1', 'user': self.systers_user, - 'is_member': 'Yes', 'email': 'foo@bar.com', 'type_community': 'Other', + 'location': self.location.id, 'is_member': 'Yes', 'email': 'foo@bar.com', + 'type_community': 'Other', 'community_channel': 'Existing Social Media Channels ', 'demographic_target_count': 'Foobarbar', 'purpose': 'foopurpose', 'is_avail_volunteer': 'Yes', 'count_avail_volunteer': '15', @@ -62,8 +67,12 @@ class EditCommunityRequestViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community_request = RequestCommunity.objects.create( - name="Foo", slug="foo", order=1, is_member='Yes', type_community='Other', + name="Foo", slug="foo", order=1, location=self.location, is_member='Yes', + type_community='Other', community_channel='Existing Social Media Channels ', is_avail_volunteer='Yes', count_avail_volunteer=0, user=self.systers_user) @@ -100,7 +109,8 @@ def test_get_edit_community_request_view(self): def test_post_edit_community_request_view(self): url = reverse('edit_community_request', kwargs={'slug': 'foo'}) # Test without logging in,and posting data - valid_data = {'name': 'Bar', 'slug': 'bar', 'order': '1', 'user': self.systers_user, + valid_data = {'name': 'Bar', 'slug': 'bar', 'order': '1', + 'location': self.location.id, 'user': self.systers_user, 'is_member': 'Yes', 'email': 'foo@bar.com', 'type_community': 'Other', 'community_channel': 'Existing Social Media Channels ', 'demographic_target_count': 'Foobarbar', 'purpose': 'foopurpose', @@ -137,8 +147,12 @@ class ViewCommunityRequestViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community_request = RequestCommunity.objects.create( - name="Foo", slug="foo", order=1, is_member='Yes', type_community='Other', + name="Foo", slug="foo", order=1, location=location, is_member='Yes', + type_community='Other', community_channel='Existing Social Media Channels ', is_avail_volunteer='Yes', count_avail_volunteer=0, user=self.systers_user) @@ -195,8 +209,12 @@ class NewCommunityRequestsListViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community_request = RequestCommunity.objects.create( - name="Foo", slug="foo", order=1, is_member='Yes', type_community='Other', + name="Foo", slug="foo", order=1, location=location, is_member='Yes', + type_community='Other', community_channel='Existing Social Media Channels ', is_avail_volunteer='Yes', count_avail_volunteer=0, user=self.systers_user) @@ -228,8 +246,12 @@ def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) self.password = 'foobar' + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community_request = RequestCommunity.objects.create( - name="Foo", slug="foo", order=1, is_member='Yes', type_community='Other', + name="Foo", slug="foo", order=1, location=location, is_member='Yes', + type_community='Other', community_channel='Existing Social Media Channels ', is_avail_volunteer='Yes', count_avail_volunteer=0, user=self.systers_user) @@ -287,8 +309,12 @@ def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) self.password = 'foobar' + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community_request = RequestCommunity.objects.create( - name="Foo", slug="foo", order=1, is_member='Yes', type_community='Other', + name="Foo", slug="foo", order=1, location=self.location, is_member='Yes', + type_community='Other', community_channel='Existing Social Media Channels ', is_avail_volunteer='Yes', count_avail_volunteer=0, user=self.systers_user) @@ -323,7 +349,7 @@ def test_approve_request_community_view_order(self): username='foo-bar', email='abcd@gmail.com', password=self.password) admin_systers_user = SystersUser.objects.get(user=admin) Community.objects.create(name="FooBarComm", slug="foobar", - order=1, admin=admin_systers_user) + order=1, location=self.location, admin=admin_systers_user) self.client.login(username='foo-bar', password='foobar') response = self.client.get(url) self.assertEqual(response.status_code, 302) @@ -342,7 +368,7 @@ def test_approve_request_community_view_slug(self): username='foo-bar', email='abcd@gmail.com', password=self.password) admin_systers_user = SystersUser.objects.get(user=admin) Community.objects.create(name="FooBarComm", slug="foo", - order=2, admin=admin_systers_user) + order=2, location=self.location, admin=admin_systers_user) self.client.login(username='foo-bar', password='foobar') response = self.client.get(url) self.assertEqual(response.status_code, 302) @@ -353,8 +379,11 @@ class ViewCommunityProfileViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_view_community_profile_view(self): @@ -379,8 +408,11 @@ def setUp(self): dispatch_uid="remove_groups") self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=self.location, admin=self.systers_user) def test_get_edit_community_profile_view(self): @@ -415,7 +447,8 @@ def test_post_edit_community_profile_view(self): url = reverse('edit_community_profile', kwargs={'slug': 'foo'}) data = {'name': 'Bar', 'slug': 'bar', - 'order': 1} + 'order': 1, + 'location': self.location.id} response = self.client.post(url, data=data) self.assertEqual(response.status_code, 403) self.client.login(username='foo', password='foobar') @@ -443,8 +476,11 @@ class CommunityLandingViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_get_community_landing_view(self): @@ -466,8 +502,11 @@ class CommunityPageViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) CommunityPage.objects.create(slug="page", title="Page", order=1, author=self.systers_user, @@ -574,6 +613,9 @@ class AddCommunityViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + self.location = City.objects.create(name='Foo', display_name='Foo', + country=country) def test_get_add_community_view(self): """Test GET request to add a new community""" @@ -616,7 +658,8 @@ def test_post_add_community_view(self): self.client.login(username='foo-bar', password='foobar') data = {'name': 'Bar', 'slug': 'foo', - 'order': '1'} + 'order': '1', + 'location': self.location.id} response = self.client.post(url, data=data) self.assertEqual(response.status_code, 302) @@ -625,8 +668,11 @@ class AddCommunityPageViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_get_add_community_page_view(self): @@ -675,8 +721,11 @@ class EditCommunityPageViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) self.page = CommunityPage.objects.create(slug="bar", title="Bar", order=1, @@ -726,8 +775,11 @@ class DeleteCommunityPageViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) CommunityPage.objects.create(slug="bar", title="Bar", order=1, author=self.systers_user, @@ -764,8 +816,11 @@ class CommunityUsersViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) CommunityPage.objects.create(slug="bar", title="Bar", order=1, author=self.systers_user, @@ -820,8 +875,11 @@ class UserPermissionGroupsViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_get_user_permissions_groups(self): @@ -871,3 +929,67 @@ def test_post_user_permissions_groups(self): response = self.client.post(url, data={}) self.assertEqual(response.status_code, 302) self.assertFalse(self.systers_user.is_group_member(group)) + + +class CommunitySearchViewTestCase(TestCase): + def setUp(self): + self.user = User.objects.create_user(username='Test', password='foobar') + self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Test Country', continent='AS') + location = City.objects.create(name='Test City', display_name='Test City', + latitude=20, longitude=20, + country=country) + self.community1 = Community.objects.create(name="Foo", slug="foo", + order=1, location=location, + admin=self.systers_user) + self.community2 = Community.objects.create(name="Bar", slug="bar", + order=2, location=location, + admin=self.systers_user) + self.community3 = Community.objects.create(name="Baz", slug="baz", + order=3, location=location, + admin=self.systers_user) + + def test_search_results(self): + url = reverse('search') + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'community/community_search.html') + self.assertEqual(len(response.context['communities']), 3) + + response = self.client.get('/community/search/?query=') + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'community/community_search.html') + self.assertEqual(len(response.context['communities']), 3) + self.assertContains(response, "Foo") + self.assertContains(response, "Bar") + self.assertContains(response, "Baz") + + response = self.client.get('/community/search/?query=B') + self.assertEqual(len(response.context['communities']), 2) + self.assertContains(response, "Bar") + self.assertContains(response, "Baz") + self.assertNotContains(response, "Foo") + + response = self.client.get('/community/search/?query=Ba') + self.assertEqual(len(response.context['communities']), 2) + self.assertContains(response, "Bar") + self.assertContains(response, "Baz") + self.assertNotContains(response, "Foo") + + response = self.client.get('/community/search/?query=Bar') + self.assertEqual(len(response.context['communities']), 1) + self.assertContains(response, "Bar") + self.assertNotContains(response, "Baz") + self.assertNotContains(response, "Foo") + + response = self.client.get('/community/search/?query=F') + self.assertEqual(len(response.context['communities']), 1) + self.assertNotContains(response, "Bar") + self.assertNotContains(response, "Baz") + self.assertContains(response, "Foo") + + response = self.client.get('/community/search/?query=Foooo') + self.assertEqual(len(response.context['communities']), 0) + self.assertNotContains(response, "Bar") + self.assertNotContains(response, "Baz") + self.assertNotContains(response, "Foo") diff --git a/systers_portal/community/urls.py b/systers_portal/community/urls.py index c2164c0d..e09cdf2f 100644 --- a/systers_portal/community/urls.py +++ b/systers_portal/community/urls.py @@ -1,18 +1,19 @@ from django.conf.urls import url -from community.views import (CommunityLandingView, EditCommunityProfileView, - ViewCommunityProfileView, CommunityPageView, - AddCommunityPageView, EditCommunityPageView, - DeleteCommunityPageView, CommunityUsersView, - UserPermissionGroupsView, RequestCommunityView, - NewCommunityRequestsListView, ApproveRequestCommunityView, - RejectRequestCommunityView, ViewCommunityRequestView, - EditCommunityRequestView, AddCommunityView) +from .views import (CommunityLandingView, EditCommunityProfileView, + ViewCommunityProfileView, CommunityPageView, + AddCommunityPageView, EditCommunityPageView, + DeleteCommunityPageView, CommunityUsersView, + UserPermissionGroupsView, RequestCommunityView, + NewCommunityRequestsListView, ApproveRequestCommunityView, + RejectRequestCommunityView, ViewCommunityRequestView, + EditCommunityRequestView, AddCommunityView, CommunitySearch) urlpatterns = [ url(r'add_community/$', AddCommunityView.as_view(), name='add_community'), + url(r'search/$', CommunitySearch.as_view(), name="search"), url(r'request_community/$', RequestCommunityView.as_view(), name='request_community'), url(r'community_requests', NewCommunityRequestsListView.as_view(), diff --git a/systers_portal/community/views.py b/systers_portal/community/views.py index 841121ac..56ef8b75 100644 --- a/systers_portal/community/views.py +++ b/systers_portal/community/views.py @@ -1,7 +1,9 @@ from django.contrib.auth.models import User from django.contrib import messages -from django.core.urlresolvers import reverse -from django.shortcuts import get_object_or_404 +from django.urls import reverse +from django.http import JsonResponse +from django.shortcuts import get_object_or_404, render +from django.template.loader import render_to_string from django.views.generic import DetailView, RedirectView, ListView, FormView from django.views.generic.edit import UpdateView, CreateView, DeleteView from braces.views import LoginRequiredMixin, PermissionRequiredMixin, StaffuserRequiredMixin @@ -19,6 +21,8 @@ from community.models import Community, CommunityPage, RequestCommunity from users.models import SystersUser +from systers_portal.settings.base import GOOGLE_MAPS_API_KEY + class RequestCommunityView(LoginRequiredMixin, CreateView): """View to Request a new community""" @@ -226,11 +230,9 @@ class CommunityLandingView(RedirectView): def get_redirect_url(self, *args, **kwargs): """Provide a redirect url based on the following conditions: - * if a Community has no pages, redirect to the news list views * if a Community has at least one page, redirect to the page with the - lowest order (aka first page) - """ + lowest order (aka first page)""" community = get_object_or_404(Community, slug=kwargs['slug']) community_pages = CommunityPage.objects.filter( community=community).order_by('order') @@ -257,6 +259,7 @@ class EditCommunityProfileView(LoginRequiredMixin, PermissionRequiredMixin, model = Community form_class = EditCommunityForm raise_exception = True + # TODO: add `redirect_unauthenticated_users = True` when django-braces will # reach version 1.5 @@ -288,22 +291,17 @@ def get_context_data(self, **kwargs): def get_community(self): """Overrides the method from CommunityMenuMixin to extract the current community. - - :return: Community object - """ + :return: Community object""" return self.object def get_page_slug(self): """Overrides the method from CommunityMenuMixin to extract the current page slug or the lack of it. - - :return: string CommunityPage slug - """ + :return: string CommunityPage slug""" return self.kwargs['page_slug'] class AddCommunityView(LoginRequiredMixin, PermissionRequiredMixin, CreateView): - template_name = "community/add_community.html" model = Community form_class = AddCommunityForm @@ -336,6 +334,7 @@ class AddCommunityPageView(LoginRequiredMixin, PermissionRequiredMixin, model = CommunityPage form_class = AddCommunityPageForm raise_exception = True + # TODO: add `redirect_unauthenticated_users = True` when django-braces will # reach version 1.5 @@ -377,6 +376,7 @@ class EditCommunityPageView(LoginRequiredMixin, PermissionRequiredMixin, slug_url_kwarg = "page_slug" form_class = EditCommunityPageForm raise_exception = True + # TODO: add `redirect_unauthenticated_users = True` when django-braces will # reach version 1.5 @@ -407,6 +407,7 @@ class DeleteCommunityPageView(LoginRequiredMixin, PermissionRequiredMixin, model = CommunityPage slug_url_kwarg = "page_slug" raise_exception = True + # TODO: add `redirect_unauthenticated_users = True` when django-braces will # reach version 1.5 @@ -436,6 +437,7 @@ class CommunityUsersView(LoginRequiredMixin, PermissionRequiredMixin, template_name = "community/users.html" paginate_by = 50 raise_exception = True + # TODO: add `redirect_unauthenticated_users = True` when django-braces will # reach version 1.5 @@ -469,6 +471,7 @@ class UserPermissionGroupsView(LoginRequiredMixin, PermissionRequiredMixin, template_name = "community/permissions.html" form_class = PermissionGroupsForm raise_exception = True + # TODO: add `redirect_unauthenticated_users = True` when django-braces will # reach version 1.5 @@ -506,3 +509,28 @@ def check_permissions(self, request): self.community = get_object_or_404(Community, slug=self.kwargs['slug']) return request.user.has_perm("change_community_systersuser", self.community) + + +class CommunitySearch(ListView): + """Search for Communities View""" + template_name = "community/community_search.html" + model = Community + + def get(self, request): + if request.method == 'GET': + context = {} + url_parameter = request.GET.get("query") + if url_parameter: + communities = Community.objects.filter(name__icontains=url_parameter) + else: + communities = Community.objects.all() + context['communities'] = communities + context['api_key'] = GOOGLE_MAPS_API_KEY + if request.is_ajax(): + html = render_to_string( + template_name="community/snippets/search-snippet.html", + context={"communities": communities} + ) + data_dict = {"html": html} + return JsonResponse(data=data_dict) + return render(request, "community/community_search.html", context=context) diff --git a/systers_portal/meetup/admin.py b/systers_portal/meetup/admin.py index 20d0711c..577763c7 100644 --- a/systers_portal/meetup/admin.py +++ b/systers_portal/meetup/admin.py @@ -1,12 +1,8 @@ from django.contrib import admin -from meetup.models import (Meetup, MeetupLocation, Rsvp, SupportRequest, RequestMeetupLocation, - RequestMeetup) +from meetup.models import (Meetup, Rsvp, SupportRequest, RequestMeetup) - -admin.site.register(MeetupLocation) admin.site.register(Meetup) admin.site.register(Rsvp) admin.site.register(SupportRequest) admin.site.register(RequestMeetup) -admin.site.register(RequestMeetupLocation) diff --git a/systers_portal/meetup/forms.py b/systers_portal/meetup/forms.py index 753aff62..0d4e73ea 100644 --- a/systers_portal/meetup/forms.py +++ b/systers_portal/meetup/forms.py @@ -1,65 +1,35 @@ from django import forms from django.utils import timezone -from django.contrib.auth.models import User -from django.shortcuts import get_object_or_404 from common.forms import ModelFormWithHelper from common.helpers import SubmitCancelFormHelper -from meetup.models import (Meetup, MeetupLocation, Rsvp, SupportRequest, RequestMeetupLocation, +from meetup.models import (Meetup, Rsvp, SupportRequest, RequestMeetup) from users.models import SystersUser from common.models import Comment -from pinax.notifications import models as notification - - -class RequestMeetupLocationForm(ModelFormWithHelper): - """ Form to create a new Request Meetup Location by a systers user. """ - class Meta: - model = RequestMeetupLocation - fields = ('name', 'slug', 'location', 'description', 'email') - helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'list_meetup_location' %}" - - def __init__(self, *args, **kwargs): - self.user = kwargs.pop('user') - super(RequestMeetupLocationForm, self).__init__(*args, **kwargs) - - def save(self, commit=True): - """Override save to add requestor to the instance""" - instance = super(RequestMeetupLocationForm, self).save(commit=False) - instance.user = SystersUser.objects.get(user=self.user) - if commit: - instance.save() - return instance class RequestMeetupForm(ModelFormWithHelper): """ Form to create a new Meetup Request. """ + class Meta: model = RequestMeetup - fields = ('title', 'slug', 'date', 'time', 'venue', 'description') + fields = ('title', 'slug', 'date', 'time', 'venue', 'meetup_location', 'description') widgets = {'date': forms.DateInput(attrs={'type': 'text', 'class': 'datepicker'}), 'time': forms.TimeInput(attrs={'type': 'text', 'class': 'timepicker'})} helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'about_meetup_location' meetup_location.slug %}" + helper_cancel_href = "{% url 'index' %}" def __init__(self, *args, **kwargs): self.user = kwargs.pop('created_by') - self.meetup_location = kwargs.pop('meetup_location') super(RequestMeetupForm, self).__init__(*args, **kwargs) def save(self, commit=True): """Override save to add admin to the instance""" instance = super(RequestMeetupForm, self).save(commit=False) instance.created_by = SystersUser.objects.get(user=self.user) - instance.meetup_location = self.meetup_location - moderators = [syster.user for syster in instance.meetup_location.moderators.all()] if commit: instance.save() - notification.send(moderators, 'new_meetup_request', - {'meetup_location': instance.meetup_location, - 'systersuser': instance.created_by, - 'meetup_request': instance}) return instance def clean_date(self): @@ -89,29 +59,28 @@ class AddMeetupForm(ModelFormWithHelper): * created_by - currently logged in user * meetup_location - to which Meetup belongs """ + class Meta: model = Meetup - fields = ('title', 'slug', 'date', 'time', 'venue', 'description', 'meetup_picture') + fields = ('title', 'slug', 'date', 'time', 'meetup_location', 'venue', 'description', + 'meetup_picture') widgets = {'date': forms.DateInput(attrs={'type': 'text', 'class': 'datepicker'}), 'time': forms.TimeInput(attrs={'type': 'text', 'class': 'timepicker'})} helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'about_meetup_location' meetup_location.slug %}" + helper_cancel_href = "{% url 'index' %}" def __init__(self, *args, **kwargs): self.created_by = kwargs.pop('created_by') - self.meetup_location = kwargs.pop('meetup_location') + self.leader = kwargs.pop('leader') super(AddMeetupForm, self).__init__(*args, **kwargs) def save(self, commit=True): """Override save to add created_by and meetup_location to the instance""" instance = super(AddMeetupForm, self).save(commit=False) instance.created_by = SystersUser.objects.get(user=self.created_by) - instance.meetup_location = self.meetup_location - members = [systers_user.user for systers_user in self.meetup_location.members.all()] + instance.leader = SystersUser.objects.get(user=self.created_by) if commit: instance.save() - notification.send(members, 'new_meetup', {'meetup_location': self.meetup_location, - 'meetup': instance}) return instance def clean_date(self): @@ -134,86 +103,24 @@ def clean_time(self): class EditMeetupForm(ModelFormWithHelper): """Form to edit Meetup""" + class Meta: model = Meetup fields = ('title', 'slug', 'date', 'time', 'description', 'venue') widgets = {'date': forms.DateInput(attrs={'type': 'date', 'class': 'datepicker'}), 'time': forms.TimeInput(attrs={'type': 'time', 'class': 'timepicker'})} helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'view_meetup' meetup_location.slug meetup.slug %}" - - -class AddMeetupLocationMemberForm(ModelFormWithHelper): - """Form for adding a new member to a meetup location""" - class Meta: - model = User - fields = ('username',) - helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'members_meetup_location' meetup_location.slug %}" - - def save(self, commit=True): - """Override save to map input username to User and append it to the meetup location. Also, - send the corresponding user the relevent notification.""" - instance = super(AddMeetupLocationMemberForm, self).save(commit=False) - user = get_object_or_404(User, username=self.username) - systersuser = get_object_or_404(SystersUser, user=user) - if systersuser not in instance.members.all(): - instance.members.add(systersuser) - notification.send([user], 'joined_meetup_location', {'meetup_location': instance}) - if commit: - instance.save() - return instance - - def clean(self): - """Check that only the username of an existing systers user is given""" - cleaned_data = super(AddMeetupLocationMemberForm, self).clean() - self.username = cleaned_data.get('username') - - if len(User.objects.filter(username=self.username)) != 1: - raise forms.ValidationError("Enter username of an existing user") - - -class AddMeetupLocationForm(ModelFormWithHelper): - """Form to create new Meetup Location""" - class Meta: - model = MeetupLocation - fields = ('name', 'slug', 'location', 'description', 'email', 'sponsors') - helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'list_meetup_location' %}" - - def __init__(self, *args, **kwargs): - self.user = kwargs.pop('user') - super(AddMeetupLocationForm, self).__init__(*args, **kwargs) - - def save(self, commit=True): - """Override save to add the request user to the meetup location's members, - leader and moderators to the instance""" - instance = super(AddMeetupLocationForm, self).save(commit=False) - systersuser = SystersUser.objects.get(user=self.user) - if commit: - instance.leader = systersuser - instance.save() - instance.members.add(systersuser) - instance.moderators.add(systersuser) - return instance - - -class EditMeetupLocationForm(ModelFormWithHelper): - """Form to edit Meetup Location""" - class Meta: - model = MeetupLocation - fields = ('name', 'slug', 'location', 'description', 'email', 'sponsors') - helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'about_meetup_location' meetup_location.slug %}" + helper_cancel_href = "{% url 'view_meetup' meetup.slug %}" class AddMeetupCommentForm(ModelFormWithHelper): """Form to add a comment to a Meetup""" + class Meta: model = Comment fields = ('body',) helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'view_meetup' meetup_location.slug meetup.slug %}" + helper_cancel_href = "{% url 'view_meetup' meetup.slug %}" def __init__(self, *args, **kwargs): self.content_object = kwargs.pop('content_object') @@ -232,20 +139,22 @@ def save(self, commit=True): class EditMeetupCommentForm(ModelFormWithHelper): """Form to edit a comment for a Meetup""" + class Meta: model = Comment fields = ('body',) helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'view_meetup' meetup_location.slug meetup.slug %}" + helper_cancel_href = "{% url 'view_meetup' meetup.slug %}" class RsvpForm(ModelFormWithHelper): """Form to add RSVP""" + class Meta: model = Rsvp fields = ('coming', 'plus_one') helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'view_meetup' meetup_location.slug meetup.slug %}" + helper_cancel_href = "{% url 'view_meetup' meetup.slug %}" def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') @@ -264,11 +173,12 @@ def save(self, commit=True): class AddSupportRequestForm(ModelFormWithHelper): """Form to add a new Support Request""" + class Meta: model = SupportRequest fields = ('description',) helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'view_meetup' meetup_location.slug meetup.slug %}" + helper_cancel_href = "{% url 'view_meetup' meetup.slug %}" def __init__(self, *args, **kwargs): self.volunteer = kwargs.pop('volunteer') @@ -281,32 +191,29 @@ def save(self, commit=True): instance = super(AddSupportRequestForm, self).save(commit=False) instance.volunteer = SystersUser.objects.get(user=self.volunteer) instance.meetup = self.meetup - moderators = [syster.user for syster in instance.meetup.meetup_location.moderators.all()] if commit: instance.save() - notification.send(moderators, 'new_support_request', - {'meetup_location': instance.meetup.meetup_location, - 'meetup': instance.meetup, 'systersuser': instance.volunteer, - 'support_request': instance}) return instance class EditSupportRequestForm(ModelFormWithHelper): """Form to edit a Support Request""" + class Meta: model = SupportRequest fields = ('description',) helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'view_meetup' meetup_location.slug meetup.slug %}" + helper_cancel_href = "{% url 'view_meetup' meetup.slug %}" class AddSupportRequestCommentForm(ModelFormWithHelper): """Form to add a comment to a Support Request""" + class Meta: model = Comment fields = ('body',) helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'view_support_request' meetup_location.slug meetup.slug" \ + helper_cancel_href = "{% url 'view_support_request' meetup.slug" \ " support_request.pk %}" def __init__(self, *args, **kwargs): @@ -326,9 +233,10 @@ def save(self, commit=True): class EditSupportRequestCommentForm(ModelFormWithHelper): """Form to edit a comment for a Support Request""" + class Meta: model = Comment fields = ('body',) helper_class = SubmitCancelFormHelper - helper_cancel_href = "{% url 'view_support_request' meetup_location.slug meetup.slug" \ + helper_cancel_href = "{% url 'view_support_request' meetup.slug" \ " support_request.pk %}" diff --git a/systers_portal/meetup/migrations/0001_initial.py b/systers_portal/meetup/migrations/0001_initial.py index 9ab4eec6..95b90f40 100644 --- a/systers_portal/meetup/migrations/0001_initial.py +++ b/systers_portal/meetup/migrations/0001_initial.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2018-08-08 17:45 -from __future__ import unicode_literals +# Generated by Django 3.0.8 on 2020-07-24 20:45 import ckeditor.fields from django.db import migrations, models @@ -12,9 +10,6 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('cities_light', '0006_compensate_for_0003_bytestring_bug'), - ('users', '0001_squashed_0003_auto_20160207_1550'), - ('cities_light', '0006_compensate_for_0003_bytestring_bug'), ] operations = [ @@ -31,26 +26,10 @@ class Migration(migrations.Migration): ('venue', models.CharField(blank=True, max_length=512, verbose_name='Venue')), ('description', models.TextField(verbose_name='Description')), ('last_updated', models.DateTimeField(auto_now=True, verbose_name='Last Update')), - ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Created By')), - ], - ), - migrations.CreateModel( - name='MeetupLocation', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255, unique=True, verbose_name='Name')), - ('slug', models.SlugField(max_length=150, unique=True, verbose_name='Slug')), - ('description', ckeditor.fields.RichTextField(verbose_name='Description')), - ('email', models.EmailField(blank=True, max_length=255, verbose_name='Email')), - ('sponsors', ckeditor.fields.RichTextField(blank=True, verbose_name='Sponsors')), - ('join_requests', models.ManyToManyField(blank=True, related_name='Join_Requests', to='users.SystersUser', verbose_name='Join Requests')), - ('leader', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='community_leader', to='users.SystersUser', verbose_name='Community leader')), - ('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cities_light.City', verbose_name='Location')), - ('members', models.ManyToManyField(blank=True, related_name='community_members', to='users.SystersUser', verbose_name='Community Members')), - ('moderators', models.ManyToManyField(related_name='community_moderators', to='users.SystersUser', verbose_name='Community Moderators')), + ('meetup_picture', models.ImageField(blank=True, null=True, upload_to='meetup/pictures/', verbose_name='Meetup picture')), ], options={ - 'permissions': (('add_meetup_location_member', 'Add meetup location member'), ('delete_meetup_location_member', 'Delete meetup location member'), ('add_meetup_location_moderator', 'Add meetup location moderator'), ('delete_meetup_location_moderator', 'Delete meetup location moderator'), ('approve_meetup_location_joinrequest', 'Approve meetup location join request'), ('reject_meetup_location_joinrequest', 'Reject meetup location join request'), ('approve_meetup_location_meetuprequest', 'Approve meetup location meetup request'), ('reject_meetup_location_meetuprequest', 'Reject meetup location meetup request'), ('view_meetup_location_meetuprequest', 'View meetup location meetup request'), ('approve_meetup_comment', 'Approve comment for a meetup'), ('reject_meetup_comment', 'Reject comment for a meetup'), ('add_meetup_rsvp', 'RSVP for a meetup'), ('approve_support_request', 'Approve support request'), ('reject_support_request', 'Reject support request'), ('add_support_request_comment', 'Add comment for a support request'), ('edit_support_request_comment', 'Edit comment for a support request'), ('delete_support_request_comment', 'Delete comment for a support request'), ('approve_support_request_comment', 'Approve comment for a support request'), ('reject_support_request_comment', 'Reject comment for a support request')), + 'permissions': (('view_meetup_request', 'View Meetup Request'), ('approve_meetup_request', 'Approve Meetup Request'), ('reject_meetup_request', 'Reject Meetup Request'), ('add_meetups', 'Add Meetups'), ('delete_meetups', 'Delete Meetup'), ('change_meetups', 'Change Meetup'), ('add_meetup_rsvp', 'Add Meetup RSVP'), ('add_support_request', 'Add Support Request'), ('edit_support_request', 'Edit Support Request'), ('delete_support_request', 'Delete Support Request'), ('approve_support_request', 'Approve Support Request'), ('reject_support_request', 'Reject Support Request'), ('add_support_request_comment', 'Add Support Request Comment')), }, ), migrations.CreateModel( @@ -65,24 +44,6 @@ class Migration(migrations.Migration): ('description', ckeditor.fields.RichTextField(verbose_name='Description')), ('date_created', models.DateTimeField(auto_now_add=True)), ('is_approved', models.BooleanField(default=False)), - ('approved_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='approvedBy', to='users.SystersUser')), - ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Created By')), - ('meetup_location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='meetup.MeetupLocation', verbose_name='Meetup Location')), - ], - ), - migrations.CreateModel( - name='RequestMeetupLocation', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255, unique=True, verbose_name='Name of the Meetup Location.(Naming convention for Systers meetup location is City+Systers.e.g.London Systers, Boston Systers.)')), - ('slug', models.SlugField(max_length=150, unique=True, verbose_name='Slug of the Meetup Location')), - ('description', ckeditor.fields.RichTextField(verbose_name='Description of the Meetup Location')), - ('email', models.EmailField(blank=True, max_length=255, verbose_name='Email of the Meetup Location if any.')), - ('date_created', models.DateTimeField(auto_now_add=True, verbose_name='Date Created')), - ('is_approved', models.BooleanField(default=False, verbose_name='Is this Approved?')), - ('approved_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='approvedby', to='users.SystersUser', verbose_name='Approved By')), - ('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cities_light.City', verbose_name='Location')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='createdby', to='users.SystersUser', verbose_name='Requested By')), ], ), migrations.CreateModel( @@ -91,8 +52,6 @@ class Migration(migrations.Migration): ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('coming', models.BooleanField(default=True)), ('plus_one', models.BooleanField(default=False)), - ('meetup', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='meetup.Meetup', verbose_name='Meetup')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='User')), ], ), migrations.CreateModel( @@ -102,16 +61,6 @@ class Migration(migrations.Migration): ('description', models.TextField(blank=True, verbose_name='Description')), ('is_approved', models.BooleanField(default=False)), ('meetup', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='meetup.Meetup', verbose_name='Meetup')), - ('volunteer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Volunteer')), ], ), - migrations.AddField( - model_name='meetup', - name='meetup_location', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='meetup.MeetupLocation', verbose_name='Meetup Location'), - ), - migrations.AlterUniqueTogether( - name='rsvp', - unique_together=set([('user', 'meetup')]), - ), ] diff --git a/systers_portal/meetup/migrations/0002_auto_20200724_2045.py b/systers_portal/meetup/migrations/0002_auto_20200724_2045.py new file mode 100644 index 00000000..bfe17789 --- /dev/null +++ b/systers_portal/meetup/migrations/0002_auto_20200724_2045.py @@ -0,0 +1,67 @@ +# Generated by Django 3.0.8 on 2020-07-24 20:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('users', '0001_initial'), + ('cities_light', '0009_add_subregion'), + ('meetup', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='supportrequest', + name='volunteer', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Volunteer'), + ), + migrations.AddField( + model_name='rsvp', + name='meetup', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='meetup.Meetup', verbose_name='Meetup'), + ), + migrations.AddField( + model_name='rsvp', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='User'), + ), + migrations.AddField( + model_name='requestmeetup', + name='approved_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='approvedBy', to='users.SystersUser'), + ), + migrations.AddField( + model_name='requestmeetup', + name='created_by', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Created By'), + ), + migrations.AddField( + model_name='requestmeetup', + name='meetup_location', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cities_light.City', verbose_name='Meetup Location'), + ), + migrations.AddField( + model_name='meetup', + name='created_by', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='users.SystersUser', verbose_name='Created By'), + ), + migrations.AddField( + model_name='meetup', + name='leader', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='community_leader', to='users.SystersUser', verbose_name='Community leader'), + ), + migrations.AddField( + model_name='meetup', + name='meetup_location', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cities_light.City', verbose_name='Meetup Location'), + ), + migrations.AlterUniqueTogether( + name='rsvp', + unique_together={('user', 'meetup')}, + ), + ] diff --git a/systers_portal/meetup/migrations/0002_meetup_meetup_picture.py b/systers_portal/meetup/migrations/0002_meetup_meetup_picture.py deleted file mode 100644 index 3245b250..00000000 --- a/systers_portal/meetup/migrations/0002_meetup_meetup_picture.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.6 on 2020-03-16 14:26 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('meetup', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='meetup', - name='meetup_picture', - field=models.ImageField(blank=True, null=True, upload_to='meetup/pictures/', verbose_name='Meetup picture'), - ), - ] diff --git a/systers_portal/meetup/mixins.py b/systers_portal/meetup/mixins.py deleted file mode 100644 index 09e2acbe..00000000 --- a/systers_portal/meetup/mixins.py +++ /dev/null @@ -1,23 +0,0 @@ -from django.core.exceptions import ImproperlyConfigured - - -class MeetupLocationMixin(object): - """Mixin to add information about MeetupLocation to context, as per the slug""" - meetup_location = None - - def get_context_data(self, **kwargs): - context = super(MeetupLocationMixin, self).get_context_data(**kwargs) - context['meetup_location'] = self.get_meetup_location() - return context - - def get_meetup_location(self): - """Get a MeetupLocaiton object. - - :return: MeetupLocaiton object - :raises ImproperlyConfigured: if MeetupLocaiton is set to None - """ - if self.meetup_location is None: - raise ImproperlyConfigured('{0} is missing a meetup_location. Define ' - '{0}.meetup_location or override {0}.get_meetup_location()' - .format(self.__class__.__name__) - ) diff --git a/systers_portal/meetup/models.py b/systers_portal/meetup/models.py index e26ff3a3..a815f24d 100644 --- a/systers_portal/meetup/models.py +++ b/systers_portal/meetup/models.py @@ -2,94 +2,12 @@ from cities_light.models import City from ckeditor.fields import RichTextField - from users.models import SystersUser -class MeetupLocation(models.Model): - """Manage details of Meetup Location groups""" - name = models.CharField(max_length=255, unique=True, verbose_name="Name") - slug = models.SlugField(max_length=150, unique=True, verbose_name="Slug") - location = models.ForeignKey(City, verbose_name="Location") - description = RichTextField(verbose_name="Description") - email = models.EmailField(max_length=255, blank=True, verbose_name="Email") - leader = models.ForeignKey(SystersUser, null=True, blank=True, related_name='community_leader', - verbose_name="Community leader") - moderators = models.ManyToManyField(SystersUser, - related_name="community_moderators", - verbose_name="Community Moderators") - members = models.ManyToManyField(SystersUser, blank=True, - related_name="community_members", - verbose_name="Community Members") - sponsors = RichTextField(verbose_name="Sponsors", blank=True) - join_requests = models.ManyToManyField(SystersUser, - related_name="Join_Requests", - verbose_name="Join Requests", - blank=True) - - class Meta: - permissions = ( - ('add_meetup_location_member', 'Add meetup location member'), - ('delete_meetup_location_member', 'Delete meetup location member'), - ('add_meetup_location_moderator', 'Add meetup location moderator'), - ('delete_meetup_location_moderator', 'Delete meetup location moderator'), - ('approve_meetup_location_joinrequest', 'Approve meetup location join request'), - ('reject_meetup_location_joinrequest', 'Reject meetup location join request'), - ('approve_meetup_location_meetuprequest', 'Approve meetup location meetup request'), - ('reject_meetup_location_meetuprequest', 'Reject meetup location meetup request'), - ('view_meetup_location_meetuprequest', 'View meetup location meetup request'), - ('approve_meetup_comment', 'Approve comment for a meetup'), - ('reject_meetup_comment', 'Reject comment for a meetup'), - ('add_meetup_rsvp', 'RSVP for a meetup'), - ('approve_support_request', 'Approve support request'), - ('reject_support_request', 'Reject support request'), - ('add_support_request_comment', 'Add comment for a support request'), - ('edit_support_request_comment', 'Edit comment for a support request'), - ('delete_support_request_comment', 'Delete comment for a support request'), - ('approve_support_request_comment', 'Approve comment for a support request'), - ('reject_support_request_comment', 'Reject comment for a support request') - ) - - def __str__(self): - return self.name - - -class RequestMeetupLocation(models.Model): - """Manage details of Meetup Location requests""" - name = models.CharField(max_length=255, unique=True, verbose_name="Name of the Meetup Location." - "(Naming convention for Systers meetup location is City+Systers." - "e.g.London Systers, Boston Systers.)") - slug = models.SlugField(max_length=150, unique=True, - verbose_name="Slug of the Meetup Location") - location = models.ForeignKey(City, verbose_name="Location") - description = RichTextField( - verbose_name="Description of the Meetup Location") - email = models.EmailField(max_length=255, blank=True, - verbose_name="Email of the Meetup Location if any.") - user = models.ForeignKey( - SystersUser, related_name='createdby', verbose_name="Requested By") - approved_by = models.ForeignKey(SystersUser, blank=True, null=True, - related_name='approvedby', verbose_name="Approved By") - date_created = models.DateTimeField( - auto_now_add=True, verbose_name="Date Created") - is_approved = models.BooleanField( - default=False, verbose_name="Is this Approved?") - - def get_verbose_fields(self): - """Get verbose names of RequestMeetupLocation object's model fields - :return: list of tuples (verbosefieldname, fieldvalue) - """ - - return [(field.verbose_name, getattr(self, field.name)) for field in - RequestMeetupLocation._meta.fields] - - def __str__(self): - return self.name - - class Meetup(models.Model): """Manage details of Meetups of MeetupLocations""" - title = models.CharField(max_length=50, verbose_name="Title",) + title = models.CharField(max_length=50, verbose_name="Title", ) slug = models.SlugField(max_length=50, unique=True, verbose_name="Slug") date = models.DateField(verbose_name="Date") end_date = models.DateField(verbose_name="End Date", null=True) @@ -97,30 +15,53 @@ class Meetup(models.Model): end_time = models.TimeField(verbose_name="End Time", null=True) venue = models.CharField(max_length=512, verbose_name="Venue", blank=True) description = models.TextField(verbose_name="Description") - meetup_location = models.ForeignKey(MeetupLocation, verbose_name="Meetup Location") - created_by = models.ForeignKey(SystersUser, null=True, verbose_name="Created By") + leader = models.ForeignKey(SystersUser, null=True, blank=True, related_name='community_leader', + verbose_name="Community leader", on_delete=models.CASCADE) + meetup_location = models.ForeignKey( + City, verbose_name="Meetup Location", on_delete=models.CASCADE) + created_by = models.ForeignKey( + SystersUser, null=True, verbose_name="Created By", on_delete=models.CASCADE) last_updated = models.DateTimeField(auto_now=True, verbose_name="Last Update") meetup_picture = models.ImageField(upload_to='meetup/pictures/', blank=True, null=True, verbose_name="Meetup picture") + class Meta: + permissions = ( + ("view_meetup_request", "View Meetup Request"), + ('approve_meetup_request', 'Approve Meetup Request'), + ('reject_meetup_request', 'Reject Meetup Request'), + ('add_meetups', 'Add Meetups'), + ('delete_meetups', 'Delete Meetup'), + ('change_meetups', 'Change Meetup'), + ('add_meetup_rsvp', 'Add Meetup RSVP'), + ('add_support_request', 'Add Support Request'), + ('edit_support_request', 'Edit Support Request'), + ('delete_support_request', 'Delete Support Request'), + ('approve_support_request', 'Approve Support Request'), + ('reject_support_request', "Reject Support Request"), + ('add_support_request_comment', 'Add Support Request Comment') + ) + def __str__(self): return self.title class RequestMeetup(models.Model): """Manage details of Meetup Requests of MeetupLocations""" - title = models.CharField(max_length=50, verbose_name="Title",) + title = models.CharField(max_length=50, verbose_name="Title", ) slug = models.SlugField(max_length=50, unique=True, verbose_name="Slug") date = models.DateField(verbose_name="Date") time = models.TimeField(verbose_name="Time", blank=True) venue = models.CharField(max_length=512, verbose_name="Venue", blank=True) description = RichTextField(verbose_name="Description") - meetup_location = models.ForeignKey(MeetupLocation, verbose_name="Meetup Location") - created_by = models.ForeignKey(SystersUser, null=True, verbose_name="Created By") + meetup_location = models.ForeignKey( + City, verbose_name="Meetup Location", on_delete=models.CASCADE) + created_by = models.ForeignKey( + SystersUser, null=True, verbose_name="Created By", on_delete=models.CASCADE) approved_by = models.ForeignKey(SystersUser, blank=True, null=True, - related_name='approvedBy') + related_name='approvedBy', on_delete=models.CASCADE) date_created = models.DateTimeField(auto_now_add=True) is_approved = models.BooleanField(default=False) @@ -137,8 +78,8 @@ def __str__(self): class Rsvp(models.Model): """ Users RSVP for particular meetup """ - user = models.ForeignKey(SystersUser, verbose_name="User") - meetup = models.ForeignKey(Meetup, verbose_name="Meetup") + user = models.ForeignKey(SystersUser, verbose_name="User", on_delete=models.CASCADE) + meetup = models.ForeignKey(Meetup, verbose_name="Meetup", on_delete=models.CASCADE) coming = models.BooleanField(default=True) plus_one = models.BooleanField(default=False) @@ -151,8 +92,8 @@ def __str__(self): class SupportRequest(models.Model): """Manage details of various volunteering activities""" - volunteer = models.ForeignKey(SystersUser, verbose_name="Volunteer") - meetup = models.ForeignKey(Meetup, verbose_name="Meetup") + volunteer = models.ForeignKey(SystersUser, verbose_name="Volunteer", on_delete=models.CASCADE) + meetup = models.ForeignKey(Meetup, verbose_name="Meetup", on_delete=models.CASCADE) description = models.TextField(verbose_name="Description", blank=True) is_approved = models.BooleanField(default=False) diff --git a/systers_portal/meetup/permissions.py b/systers_portal/meetup/permissions.py index b263ec91..dbc601b4 100644 --- a/systers_portal/meetup/permissions.py +++ b/systers_portal/meetup/permissions.py @@ -6,40 +6,21 @@ community_member_permissions = [ "add_meetup_rsvp", - "add_supportrequest", - "change_supportrequest", - "delete_supportrequest" + "add_support_request" ] community_moderator_permissions = community_member_permissions + [ - "add_meetup", - "change_meetup", - "delete_meetup", - "add_meetup_location_member", - "delete_meetup_location_member", - "approve_meetup_location_joinrequest", - "reject_meetup_location_joinrequest", - "approve_meetup_location_meetuprequest", - "reject_meetup_location_meetuprequest", - "view_meetup_location_meetuprequest", - "approve_meetup_comment", - "reject_meetup_comment", + "add_meetups", + "change_meetups", + "delete_meetups", + "approve_meetup_request", + "reject_meetup_request", + "view_meetup_request", "approve_support_request", - "reject_support_request", - "add_support_request_comment", - "edit_support_request_comment", - "delete_support_request_comment", - "approve_support_request_comment", - "reject_support_request_comment" + "reject_support_request" ] -community_leader_permissions = community_moderator_permissions + [ - "change_meetuplocation", - "add_meetuplocation", - "add_meetup_location_moderator", - "delete_meetup_location_moderator", - "delete_meetuplocation", -] +community_leader_permissions = community_moderator_permissions group_permissions = {"community_member": community_member_permissions, "community_moderator": community_moderator_permissions, diff --git a/systers_portal/meetup/signals.py b/systers_portal/meetup/signals.py index 1084cefe..28654f67 100644 --- a/systers_portal/meetup/signals.py +++ b/systers_portal/meetup/signals.py @@ -1,19 +1,16 @@ -from django.db.models.signals import post_save, post_delete, m2m_changed, post_migrate +from django.db.models.signals import post_save, post_delete, post_migrate from django.dispatch import receiver -from django.contrib.auth.models import Group -from django.shortcuts import get_object_or_404 from pinax.notifications.models import NoticeType -from meetup.models import MeetupLocation -from meetup.constants import COMMUNITY_MEMBER, COMMUNITY_MODERATOR, COMMUNITY_LEADER +from meetup.models import Meetup +from meetup.constants import COMMUNITY_LEADER from meetup.utils import (create_groups, assign_permissions, remove_groups) -from users.models import SystersUser -@receiver(post_save, sender=MeetupLocation, dispatch_uid="manage_groups") -def manage_meetup_location_groups(sender, instance, created, **kwargs): +@receiver(post_save, sender=Meetup, dispatch_uid="manage_groups") +def manage_meetup_groups(sender, instance, created, **kwargs): """Manage user groups and user permissions for a particular MeetupLocation""" - name = instance.name + name = instance.title if created: groups = create_groups(name) assign_permissions(instance, groups) @@ -23,77 +20,15 @@ def manage_meetup_location_groups(sender, instance, created, **kwargs): instance.save() -@receiver(post_delete, sender=MeetupLocation, dispatch_uid="remove_groups") -def remove_meetup_location_groups(sender, instance, **kwargs): +@receiver(post_delete, sender=Meetup, dispatch_uid="remove_groups") +def remove_meetup_groups(sender, instance, **kwargs): """Remove user groups for a particular Meetup Location""" - remove_groups(instance.name) - - -@receiver(m2m_changed, sender=MeetupLocation.members.through, - dispatch_uid="add_members") -def add_meetup_location_members(sender, **kwargs): - """Add permissions to a user when she is added as a Meetup Location member""" - instance = kwargs.pop('instance', None) - action = kwargs.pop('action', None) - pk_set = kwargs.pop('pk_set', None) - if action == "pre_add": - systersuser = SystersUser.objects.get(pk=list(pk_set)[0]) - members_group = get_object_or_404(Group, name=COMMUNITY_MEMBER.format(instance.name)) - if not systersuser.is_group_member(members_group.name): - systersuser.join_group(members_group) - - -@receiver(m2m_changed, sender=MeetupLocation.moderators.through, - dispatch_uid="add_moderators") -def add_meetup_location_moderators(sender, **kwargs): - """Add permissions to a user when she is added as a Meetup Location moderator""" - instance = kwargs.pop('instance', None) - action = kwargs.pop('action', None) - pk_set = kwargs.pop('pk_set', None) - if action == "pre_add": - systersuser = SystersUser.objects.get(pk=list(pk_set)[0]) - moderators_group = get_object_or_404(Group, name=COMMUNITY_MODERATOR.format(instance.name)) - if not systersuser.is_group_member(moderators_group.name): - systersuser.join_group(moderators_group) - - -@receiver(m2m_changed, sender=MeetupLocation.members.through, - dispatch_uid="delete_members") -def delete_meetup_location_members(sender, **kwargs): - """Delete permissions from a user when she is removed as a Meetup Location member""" - instance = kwargs.pop('instance', None) - action = kwargs.pop('action', None) - pk_set = kwargs.pop('pk_set', None) - if action == "pre_remove": - systersuser = SystersUser.objects.get(pk=list(pk_set)[0]) - members_group = get_object_or_404(Group, name=COMMUNITY_MEMBER.format(instance.name)) - if systersuser.is_group_member(members_group.name): - systersuser.leave_group(members_group) - - -@receiver(m2m_changed, sender=MeetupLocation.moderators.through, - dispatch_uid="delete_moderators") -def delete_meetup_location_moderators(sender, **kwargs): - """Delete permissions from a user when she is removed as a Meetup Location moderator""" - instance = kwargs.pop('instance', None) - action = kwargs.pop('action', None) - pk_set = kwargs.pop('pk_set', None) - if action == "pre_remove": - systersuser = SystersUser.objects.get(pk=list(pk_set)[0]) - moderators_group = get_object_or_404(Group, name=COMMUNITY_MODERATOR.format(instance.name)) - if systersuser.is_group_member(moderators_group.name): - systersuser.leave_group(moderators_group) + remove_groups(instance.title) @receiver(post_migrate, dispatch_uid="create_notice_types") def create_notice_types(sender, **kwargs): """Create notice types to send email notifications""" - NoticeType.create("new_join_request", ("New Join Request"), - ("a user has requested to join the meetup location")) - NoticeType.create("joined_meetup_location", ("Joined Meetup Location"), - ("you have joined a meetup location")) - NoticeType.create("made_moderator", ("Made moderator"), - ("you have been made an moderator of a meetup location")) NoticeType.create("new_meetup", ("New Meetup"), ("a new meetup has been added")) NoticeType.create("new_support_request", ("New Support Request"), diff --git a/systers_portal/meetup/tests/test_forms.py b/systers_portal/meetup/tests/test_forms.py index d9edaac9..203b502b 100644 --- a/systers_portal/meetup/tests/test_forms.py +++ b/systers_portal/meetup/tests/test_forms.py @@ -5,15 +5,15 @@ from cities_light.models import City, Country from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError -from django.core import mail -from meetup.forms import (AddMeetupForm, EditMeetupForm, AddMeetupLocationMemberForm, - AddMeetupLocationForm, EditMeetupLocationForm, AddMeetupCommentForm, - EditMeetupCommentForm, RsvpForm, AddSupportRequestForm, + +from meetup.forms import (AddMeetupForm, EditMeetupForm, + AddMeetupCommentForm, EditMeetupCommentForm, + RsvpForm, AddSupportRequestForm, EditSupportRequestForm, AddSupportRequestCommentForm, - EditSupportRequestCommentForm, RequestMeetupLocationForm, + EditSupportRequestCommentForm, RequestMeetupForm) -from meetup.models import (Meetup, MeetupLocation, Rsvp, SupportRequest, RequestMeetupLocation, +from meetup.models import (Meetup, Rsvp, SupportRequest, RequestMeetup) from users.models import SystersUser from common.models import Comment @@ -26,71 +26,44 @@ def setUp(self): self.systers_user = SystersUser.objects.get(user=self.user) country = Country.objects.create(name='Bar', continent='AS') self.location = City.objects.create(name='Baz', display_name='Baz', country=country) - self.meetup_location = MeetupLocation.objects.create( - name="Foo Systers", slug="foo", location=self.location, - description="It's a test meetup location", sponsors="BarBaz", leader=self.systers_user) - self.meetup_location.members.add(self.systers_user) - self.meetup_location.moderators.add(self.systers_user) - self.meetup = Meetup.objects.create(title='Foo Bar Baz', slug='foobarbaz', date=timezone.now().date(), time=timezone.now().time(), description='This is test Meetup', - meetup_location=self.meetup_location, + meetup_location=self.location, created_by=self.systers_user, + leader=self.systers_user, last_updated=timezone.now()) -class RequestMeetupLocationFormTestCase(MeetupFormTestCaseBase, TestCase): - def test_add_request_meetup_location_form(self): - # Testing form with invalid data - invalid_data = {'name': 'def', 'location': 'Baz, Bar, AS'} - form = AddMeetupLocationForm(data=invalid_data, user=self.user) - self.assertFalse(form.is_valid()) - # Testing form with valid data - location_id = self.location.id - data = {'name': 'Bar Systers', 'slug': 'bar', 'location': location_id, - 'description': 'test test test.', 'email': 'abc@def.com'} - form = RequestMeetupLocationForm(data=data, user=self.user) - self.assertTrue(form.is_valid()) - form.save() - - new_meetup_location_request = RequestMeetupLocation.objects.get(slug='bar') - self.assertTrue(new_meetup_location_request.name, 'Bar Systers') - - class RequestMeetupFormTestCase(MeetupFormTestCaseBase, TestCase): def test_add_request_meetup_form(self): # Testing form with invalid data invalid_data = {'title': 'abc', 'date': timezone.now().date()} - form = RequestMeetupForm(data=invalid_data, created_by=self.user, - meetup_location=self.meetup_location) + form = RequestMeetupForm(data=invalid_data, created_by=self.user) self.assertFalse(form.is_valid()) date = (timezone.now() + timedelta(2)).date() time = timezone.now().time() data = {'title': 'Foo', 'slug': 'foo', 'date': date, 'time': time, + 'meetup_location': self.location.id, 'description': "It's a test meetup."} - form = RequestMeetupForm(data=data, created_by=self.user, - meetup_location=self.meetup_location) + form = RequestMeetupForm(data=data, created_by=self.user) self.assertTrue(form.is_valid()) form.save() new_meetup_request = RequestMeetup.objects.get(slug='foo') self.assertTrue(new_meetup_request.title, 'Foo') self.assertTrue(new_meetup_request.created_by, self.systers_user) - self.assertTrue(new_meetup_request.meetup_location, self.meetup_location) - self.assertEqual(len(mail.outbox), 1) - self.assertIn(self.user.email, mail.outbox[0].to) - self.assertIn('New Meetup Request', mail.outbox[0].subject) + self.assertTrue(new_meetup_request.meetup_location, self.location) def test_request_meetup_form_with_past_date(self): """Test add Meetup form with a date that has passed.""" date = (timezone.now() - timedelta(2)).date() time = timezone.now().time() data = {'title': 'Foo', 'slug': 'foo', 'date': date, 'time': time, + 'meetup_location': self.location, 'description': "It's a test meetup."} - form = AddMeetupForm(data=data, created_by=self.systers_user, - meetup_location=self.meetup_location) + form = AddMeetupForm(data=data, created_by=self.systers_user, leader=self.systers_user) self.assertFalse(form.is_valid()) self.assertTrue(form.errors['date'], ["Date should not be before today's date."]) @@ -99,9 +72,9 @@ def test_request_meetup_form_with_passed_time(self): date = timezone.now().date() time = (timezone.now() - timedelta(2)).time() data = {'title': 'Foo', 'slug': 'foo', 'date': date, 'time': time, + 'meetup_location': self.location, 'description': "It's a test meetup."} - form = AddMeetupForm(data=data, created_by=self.systers_user, - meetup_location=self.meetup_location) + form = AddMeetupForm(data=data, created_by=self.systers_user, leader=self.systers_user) self.assertFalse(form.is_valid()) self.assertTrue(form.errors['time'], ["Time should not be a time that has already passed."]) @@ -115,41 +88,36 @@ def setUp(self): self.user2 = User.objects.create_user(username='baz', password=self.password, email='user2@test.com') self.systers_user2 = SystersUser.objects.get(user=self.user2) - self.meetup_location.members.add(self.systers_user2) def test_add_meetup_form(self): """Test add Meetup form""" invalid_data = {'title': 'abc', 'date': timezone.now().date()} - form = AddMeetupForm(data=invalid_data, created_by=self.systers_user, - meetup_location=self.meetup_location) + form = AddMeetupForm(data=invalid_data, + created_by=self.systers_user, + leader=self.systers_user) self.assertFalse(form.is_valid()) date = (timezone.now() + timedelta(2)).date() time = timezone.now().time() data = {'title': 'Foo', 'slug': 'foo', 'date': date, 'time': time, + 'meetup_location': self.location.id, 'description': "It's a test meetup."} - form = AddMeetupForm(data=data, created_by=self.user, - meetup_location=self.meetup_location) + form = AddMeetupForm(data=data, created_by=self.user, leader=self.systers_user) self.assertTrue(form.is_valid()) form.save() new_meetup = Meetup.objects.get(slug='foo') self.assertTrue(new_meetup.title, 'Foo') self.assertTrue(new_meetup.created_by, self.systers_user) - self.assertTrue(new_meetup.meetup_location, self.meetup_location) - self.assertEqual(len(mail.outbox), 2) - self.assertIn(self.user.email, mail.outbox[0].to) - self.assertIn('New Meetup', mail.outbox[0].subject) - self.assertIn(self.user2.email, mail.outbox[1].to) - self.assertIn('New Meetup', mail.outbox[1].subject) + self.assertTrue(new_meetup.meetup_location, self.location) def test_add_meetup_form_with_past_date(self): """Test add Meetup form with a date that has passed.""" date = (timezone.now() - timedelta(2)).date() time = timezone.now().time() data = {'title': 'Foo', 'slug': 'foo', 'date': date, 'time': time, + 'meetup_location': self.location, 'description': "It's a test meetup."} - form = AddMeetupForm(data=data, created_by=self.systers_user, - meetup_location=self.meetup_location) + form = AddMeetupForm(data=data, created_by=self.systers_user, leader=self.systers_user) self.assertFalse(form.is_valid()) self.assertTrue(form.errors['date'], ["Date should not be before today's date."]) @@ -158,9 +126,9 @@ def test_add_meetup_form_with_passed_time(self): date = timezone.now().date() time = (timezone.now() - timedelta(2)).time() data = {'title': 'Foo', 'slug': 'foo', 'date': date, 'time': time, + 'meetup_location': self.location, 'description': "It's a test meetup."} - form = AddMeetupForm(data=data, created_by=self.systers_user, - meetup_location=self.meetup_location) + form = AddMeetupForm(data=data, created_by=self.systers_user, leader=self.systers_user) self.assertFalse(form.is_valid()) self.assertTrue(form.errors['time'], ["Time should not be a time that has already passed."]) @@ -185,70 +153,7 @@ def test_edit_meetup_form(self): self.assertEqual(meetup.title, 'Foo Bar') self.assertEqual(meetup.slug, 'foobar') self.assertEqual(meetup.created_by, self.systers_user) - self.assertEqual(meetup.meetup_location, self.meetup_location) - - -class AddMeetupLocationMemberFormTestCase(MeetupFormTestCaseBase, TestCase): - def setUp(self): - super(AddMeetupLocationMemberFormTestCase, self).setUp() - self.user2 = User.objects.create_user(username='baz', password='bazbar', - email='user2@test.com') - self.systers_user2 = SystersUser.objects.get(user=self.user2) - - def test_add_meetup_location_member_form(self): - """Test add meetup location Member form""" - invalid_data = {'username': 'non_existent'} - form = AddMeetupLocationMemberForm(data=invalid_data) - self.assertFalse(form.is_valid()) - - username = self.user2.get_username() - data = {'username': username} - self.meetup_location = MeetupLocation.objects.get() - form = AddMeetupLocationMemberForm(data=data, instance=self.meetup_location) - self.assertTrue(form.is_valid()) - form.save() - - members = self.meetup_location.members.all() - self.assertTrue(self.systers_user2 in members) - self.assertEqual(len(mail.outbox), 1) - self.assertIn(self.user2.email, mail.outbox[0].to) - self.assertIn('Joined Meetup Location', mail.outbox[0].subject) - - -class AddMeetupLocationFormTestCase(MeetupFormTestCaseBase, TestCase): - def test_add_meetup_location_form(self): - """Test add Meetup Location form""" - invalid_data = {'name': 'def', 'location': 'Baz, Bar, AS'} - form = AddMeetupLocationForm(data=invalid_data, user=self.user) - self.assertFalse(form.is_valid()) - - location_id = self.location.id - data = {'name': 'Bar Systers', 'slug': 'bar', 'location': location_id, - 'description': 'test test test.', 'email': 'abc@def.com', 'sponsors': 'BaaBaa'} - form = AddMeetupLocationForm(data=data, user=self.user) - self.assertTrue(form.is_valid()) - form.save() - - new_meetup_location = MeetupLocation.objects.get(slug='bar') - self.assertTrue(new_meetup_location.name, 'Bar Systers') - - -class EditMeetupLocationFormTestCase(MeetupFormTestCaseBase, TestCase): - def test_edit_meetup_location_form(self): - """Test edit meetup location form""" - invalid_data = {'location': 4, 'sponsors': 'wrogn'} - form = EditMeetupLocationForm(data=invalid_data) - self.assertFalse(form.is_valid()) - - location_id = self.location.id - data = {'name': 'Foo Systers', 'slug': 'foo', 'location': location_id, - 'description': 'test edit', 'email': 'foo@bar.com', 'sponsors': 'test'} - form = EditMeetupLocationForm(instance=self.meetup_location, data=data) - self.assertTrue(form.is_valid()) - form.save() - meetup_location = MeetupLocation.objects.get() - self.assertEqual(meetup_location.description, 'test edit') - self.assertEqual(meetup_location.sponsors, 'test') + self.assertEqual(meetup.meetup_location, self.location) class AddMeetupCommentFormTestCase(MeetupFormTestCaseBase, TestCase): @@ -317,9 +222,6 @@ def test_add_support_request_form(self): self.assertEqual(support_requests[0].description, 'This is a test description') self.assertEqual(support_requests[0].volunteer, self.systers_user) self.assertEqual(support_requests[0].meetup, self.meetup) - self.assertEqual(len(mail.outbox), 1) - self.assertIn(self.user.email, mail.outbox[0].to) - self.assertIn('New Support Request', mail.outbox[0].subject) class EditSupportRequestFormTestCase(MeetupFormTestCaseBase, TestCase): diff --git a/systers_portal/meetup/tests/test_mixins.py b/systers_portal/meetup/tests/test_mixins.py deleted file mode 100644 index 1ef9c5e1..00000000 --- a/systers_portal/meetup/tests/test_mixins.py +++ /dev/null @@ -1,40 +0,0 @@ -from django.core.exceptions import ImproperlyConfigured -from django.contrib.auth.models import User -from django.test import TestCase -from django.views.generic import TemplateView -from cities_light.models import City, Country - -from meetup.mixins import MeetupLocationMixin -from meetup.models import MeetupLocation -from users.models import SystersUser - - -class MeetupLocationMixinTestCase(TestCase): - def setUp(self): - self.password = "foobar" - user = User.objects.create_user(username='foo', password=self.password, - email='user@test.com') - systers_user = SystersUser.objects.get(user=user) - country = Country.objects.create(name='Bar', continent='AS') - self.location = City.objects.create(name='Foo', display_name='Foo', country=country) - self.meetup_location = MeetupLocation.objects.create( - name="Foo Systers", slug="foo", location=self.location, - description="It's a test location", sponsors="BarBaz", leader=systers_user) - - def test_get_context_data_no_meetup_location(self): - """Test mixin with no meetup_location""" - class DummyView(MeetupLocationMixin, TemplateView): - pass - - view = DummyView() - self.assertRaises(ImproperlyConfigured, view.get_context_data) - - def test_get_context_data_with_meeetup_location(self): - """Test mixin with a meetup_location""" - class DummyView(MeetupLocationMixin, TemplateView): - def get_meetup_location(self): - return MeetupLocation.objects.get() - - view = DummyView() - context = view.get_context_data() - self.assertEqual(context['meetup_location'], self.meetup_location) diff --git a/systers_portal/meetup/tests/test_models.py b/systers_portal/meetup/tests/test_models.py index bd1dce0f..c70e4d91 100644 --- a/systers_portal/meetup/tests/test_models.py +++ b/systers_portal/meetup/tests/test_models.py @@ -3,37 +3,18 @@ from django.utils import timezone from cities_light.models import City, Country -from meetup.models import (Meetup, MeetupLocation, Rsvp, SupportRequest, RequestMeetupLocation, +from meetup.models import (Meetup, Rsvp, SupportRequest, RequestMeetup) from users.models import SystersUser -class MeetupBaseTestCase(): +class MeetupBaseTestCase: def setUp(self): country = Country.objects.create(name='Bar', continent='AS') self.location = City.objects.create(name='Foo', display_name='Foo', country=country) self.user = User.objects.create(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) - self.meetup_location = MeetupLocation.objects.create( - name="Foo Systers", slug="foo", location=self.location, - description="It's a test location", sponsors="BarBaz", leader=self.systers_user) - self.meetup_location_request = RequestMeetupLocation.objects.create( - name="Bar Systers", slug="bar", location=self.location, - description="This is a test meetup location request", - user=self.systers_user) - - -class MeetupLocationModelTestCase(MeetupBaseTestCase, TestCase): - def test_str(self): - """Test MeetupLocation object str/unicode representation""" - self.assertEqual(str(self.meetup_location), "Foo Systers") - - -class RequestMeetupLocationModelTestCase(MeetupBaseTestCase, TestCase): - def test_str(self): - """Test MeetupLocation object str/unicode representation""" - self.assertEqual(str(self.meetup_location_request), "Bar Systers") class MeetupTestCase(MeetupBaseTestCase, TestCase): @@ -43,8 +24,9 @@ def setUp(self): date=timezone.now().date(), time=timezone.now().time(), venue="FooBar colony", description="This is a testing meetup.", - meetup_location=self.meetup_location, - created_by=self.systers_user) + meetup_location=self.location, + created_by=self.systers_user, + leader=self.systers_user) def test_str(self): """Test Meetup object str/unicode representation""" @@ -59,7 +41,7 @@ def setUp(self): date=timezone.now().date(), time=timezone.now().time(), venue="FooBar colony", description="This is a testing meetup request.", - meetup_location=self.meetup_location, + meetup_location=self.location, created_by=self.systers_user) def test_str(self): @@ -79,7 +61,8 @@ def setUp(self): date=timezone.now().date(), time=timezone.now().time(), venue="FooBar colony", description="This is a testing meetup.", - meetup_location=self.meetup_location, + meetup_location=self.location, + leader=self.systers_user, created_by=self.systers_user) self.rsvp = Rsvp.objects.create(user=self.systers_user, meetup=self.meetup) @@ -94,7 +77,8 @@ def setUp(self): date=timezone.now().date(), time=timezone.now().time(), venue="FooBar colony", description="This is a testing meetup.", - meetup_location=self.meetup_location, + meetup_location=self.location, + leader=self.systers_user, created_by=self.systers_user) self.support_request = SupportRequest.objects.create(volunteer=self.systers_user, meetup=self.meetup, diff --git a/systers_portal/meetup/tests/test_permissions.py b/systers_portal/meetup/tests/test_permissions.py index d4ddcb22..e360a27c 100644 --- a/systers_portal/meetup/tests/test_permissions.py +++ b/systers_portal/meetup/tests/test_permissions.py @@ -10,9 +10,7 @@ def test_community_member_permissions(self): """Test member list of permissions""" permissions = [ "add_meetup_rsvp", - "add_supportrequest", - "change_supportrequest", - "delete_supportrequest" + "add_support_request" ] self.assertCountEqual(community_member_permissions, permissions) @@ -20,28 +18,15 @@ def test_community_moderator_permissions(self): """Test moderator list of permissions""" permissions = [ "add_meetup_rsvp", - "add_supportrequest", - "change_supportrequest", - "delete_supportrequest", - "add_meetup", - "change_meetup", - "delete_meetup", - "add_meetup_location_member", - "delete_meetup_location_member", - "approve_meetup_location_joinrequest", - "reject_meetup_location_joinrequest", - "approve_meetup_location_meetuprequest", - "reject_meetup_location_meetuprequest", - "view_meetup_location_meetuprequest", - "approve_meetup_comment", - "reject_meetup_comment", + "add_support_request", + "add_meetups", + "change_meetups", + "delete_meetups", + "approve_meetup_request", + "reject_meetup_request", + "view_meetup_request", "approve_support_request", "reject_support_request", - "add_support_request_comment", - "edit_support_request_comment", - "delete_support_request_comment", - "approve_support_request_comment", - "reject_support_request_comment" ] self.assertCountEqual(community_moderator_permissions, permissions) @@ -49,33 +34,15 @@ def test_community_leader_permissions(self): """Test leader list of permissions""" permissions = [ "add_meetup_rsvp", - "add_supportrequest", - "change_supportrequest", - "delete_supportrequest", - "add_meetup", - "change_meetup", - "delete_meetup", - "add_meetuplocation", - "change_meetuplocation", - "delete_meetuplocation", - "add_meetup_location_member", - "delete_meetup_location_member", - "add_meetup_location_moderator", - "delete_meetup_location_moderator", - "approve_meetup_location_joinrequest", - "reject_meetup_location_joinrequest", - "approve_meetup_location_meetuprequest", - "reject_meetup_location_meetuprequest", - "view_meetup_location_meetuprequest", - "approve_meetup_comment", - "reject_meetup_comment", + "add_support_request", + "add_meetups", + "change_meetups", + "delete_meetups", + "approve_meetup_request", + "reject_meetup_request", + "view_meetup_request", "approve_support_request", - "reject_support_request", - "add_support_request_comment", - "edit_support_request_comment", - "delete_support_request_comment", - "approve_support_request_comment", - "reject_support_request_comment" + "reject_support_request" ] self.assertCountEqual(community_leader_permissions, permissions) diff --git a/systers_portal/meetup/tests/test_signals.py b/systers_portal/meetup/tests/test_signals.py index 4068c113..3404f771 100644 --- a/systers_portal/meetup/tests/test_signals.py +++ b/systers_portal/meetup/tests/test_signals.py @@ -1,34 +1,23 @@ +from django.utils import timezone + from django.test import TestCase from django.contrib.auth.models import Group, User -from django.db.models.signals import post_save, post_delete, m2m_changed, post_migrate +from django.db.models.signals import post_save, post_delete, post_migrate from cities_light.models import City, Country from pinax.notifications.models import NoticeType -from meetup.constants import COMMUNITY_MEMBER, COMMUNITY_MODERATOR -from meetup.models import MeetupLocation -from meetup.signals import (manage_meetup_location_groups, remove_meetup_location_groups, - add_meetup_location_members, add_meetup_location_moderators, - delete_meetup_location_members, delete_meetup_location_moderators, - create_notice_types) +from meetup.models import Meetup from users.models import SystersUser +from meetup.signals import manage_meetup_groups, remove_meetup_groups, create_notice_types + class SignalsTestCase(TestCase): def setUp(self): - post_save.connect(manage_meetup_location_groups, sender=MeetupLocation, + post_save.connect(manage_meetup_groups, sender=Meetup, dispatch_uid="manage_groups") - post_delete.connect(remove_meetup_location_groups, sender=MeetupLocation, + post_delete.connect(remove_meetup_groups, sender=Meetup, dispatch_uid="remove_groups") - m2m_changed.connect(add_meetup_location_members, sender=MeetupLocation.members.through, - dispatch_uid="add_members") - m2m_changed.connect(add_meetup_location_moderators, - sender=MeetupLocation.moderators.through, - dispatch_uid="add_moderators") - m2m_changed.connect(delete_meetup_location_members, sender=MeetupLocation.members.through, - dispatch_uid="delete_members") - m2m_changed.connect(delete_meetup_location_moderators, - sender=MeetupLocation.moderators.through, - dispatch_uid="delete_moderators") post_migrate.connect(create_notice_types, dispatch_uid="create_notice_types") self.password = "foobar" @@ -39,9 +28,15 @@ def test_manage_meetup_location_groups(self): systers_user = SystersUser.objects.get(user=user) country = Country.objects.create(name='Bar', continent='AS') location = City.objects.create(name='Baz', display_name='Baz', country=country) - meetup_location = MeetupLocation.objects.create( # noqa - name="Foo", slug="foo", location=location, - description="It's a test meetup location", leader=systers_user) + meetup = Meetup.objects.create(title='Foo Bar Baz', slug='foo-bar-baz', + date=timezone.now().date(), + time=timezone.now().time(), + description='This is test Meetup', + meetup_location=location, + created_by=systers_user, + leader=systers_user, + last_updated=timezone.now()) + self.assertEqual("Foo Bar Baz", meetup.title) groups_count = Group.objects.count() self.assertEqual(groups_count, 3) @@ -52,92 +47,24 @@ def test_remove_community_groups(self): systers_user = SystersUser.objects.get(user=user) country = Country.objects.create(name='Bar', continent='AS') location = City.objects.create(name='Baz', display_name='Baz', country=country) - meetup_location = MeetupLocation.objects.create( - name="Foo", slug="foo", location=location, - description="It's a test meetup location", leader=systers_user) + meetup = Meetup.objects.create(title='Foo Bar Baz', slug='foo-bar-baz', + date=timezone.now().date(), + time=timezone.now().time(), + description='This is test Meetup', + meetup_location=location, + created_by=systers_user, + leader=systers_user, + last_updated=timezone.now()) groups_count = Group.objects.count() self.assertEqual(groups_count, 3) - meetup_location.delete() + meetup.delete() groups_count = Group.objects.count() self.assertEqual(groups_count, 0) - def test_add_meetup_location_members(self): - """Test addition of permissions to a user when she is made a meetup location member""" - - user = User.objects.create(username='foo', password=self.password) - systers_user = SystersUser.objects.get(user=user) - user2 = User.objects.create(username='foobar', password=self.password) - systers_user2 = SystersUser.objects.get(user=user2) - country = Country.objects.create(name='Bar', continent='AS') - location = City.objects.create(name='Baz', display_name='Baz', country=country) - meetup_location = MeetupLocation.objects.create( - name="Foo", slug="foo", location=location, - description="It's a test meetup location", leader=systers_user2) - meetup_location.members.add(systers_user) - members_group = Group.objects.get(name=COMMUNITY_MEMBER.format(meetup_location.name)) - self.assertEqual(user.groups.get(), members_group) - - def test_add_meetup_location_moderators(self): - """Test addition of permissions to a user when she is made a meetup location moderator""" - user = User.objects.create(username='foo', password=self.password) - systers_user = SystersUser.objects.get(user=user) - user2 = User.objects.create(username='foobar', password=self.password) - systers_user2 = SystersUser.objects.get(user=user2) - country = Country.objects.create(name='Bar', continent='AS') - location = City.objects.create(name='Baz', display_name='Baz', country=country) - meetup_location = MeetupLocation.objects.create( - name="Foo", slug="foo", location=location, - description="It's a test meetup location", leader=systers_user2) - meetup_location.moderators.add(systers_user) - moderators_group = Group.objects.get(name=COMMUNITY_MODERATOR.format(meetup_location.name)) - self.assertEqual(user.groups.get(), moderators_group) - - def test_delete_meetup_location_members(self): - """Test removal of permissions from a user when she is removed as a meetup location - member""" - user2 = User.objects.create(username='foobar', password=self.password) - systers_user2 = SystersUser.objects.get(user=user2) - user = User.objects.create(username='foo', password=self.password) - systers_user = SystersUser.objects.get(user=user) - country = Country.objects.create(name='Bar', continent='AS') - location = City.objects.create(name='Baz', display_name='Baz', country=country) - meetup_location = MeetupLocation.objects.create( - name="Foo", slug="foo", location=location, - description="It's a test meetup location", leader=systers_user2) - members_group = Group.objects.get(name=COMMUNITY_MEMBER.format(meetup_location.name)) - meetup_location.members.add(systers_user) - self.assertEqual(user.groups.get(), members_group) - meetup_location.members.remove(systers_user) - self.assertEqual(len(user.groups.all()), 0) - - def test_delete_meetup_location_moderators(self): - """Test removal of permissions from a user when she is removed as a meetup location - moderator""" - user2 = User.objects.create(username='foobar', password=self.password) - systers_user2 = SystersUser.objects.get(user=user2) - user = User.objects.create(username='foo', password=self.password) - systers_user = SystersUser.objects.get(user=user) - country = Country.objects.create(name='Bar', continent='AS') - location = City.objects.create(name='Baz', display_name='Baz', country=country) - meetup_location = MeetupLocation.objects.create( - name="Foo", slug="foo", location=location, - description="It's a test meetup location", leader=systers_user2) - moderators_group = Group.objects.get(name=COMMUNITY_MODERATOR.format(meetup_location.name)) - meetup_location.moderators.add(systers_user) - self.assertEqual(user.groups.get(), moderators_group) - meetup_location.moderators.remove(systers_user) - self.assertEqual(len(user.groups.all()), 0) - def test_create_notice_types(self): """Test creation of notice types""" notice_types = NoticeType.objects.all() - self.assertEqual(len(notice_types), 7) - new_join_request = NoticeType.objects.get(label="new_join_request") - self.assertEqual(new_join_request.display, "New Join Request") - joined_meetup_location = NoticeType.objects.get(label="joined_meetup_location") - self.assertEqual(joined_meetup_location.display, "Joined Meetup Location") - made_moderator = NoticeType.objects.get(label="made_moderator") - self.assertEqual(made_moderator.display, "Made moderator") + self.assertEqual(len(notice_types), 4) new_meetup = NoticeType.objects.get(label="new_meetup") self.assertEqual(new_meetup.display, "New Meetup") new_support_request = NoticeType.objects.get(label="new_support_request") diff --git a/systers_portal/meetup/tests/test_utils.py b/systers_portal/meetup/tests/test_utils.py index 730e092a..35168464 100644 --- a/systers_portal/meetup/tests/test_utils.py +++ b/systers_portal/meetup/tests/test_utils.py @@ -3,10 +3,10 @@ from guardian.shortcuts import get_perms from cities_light.models import City, Country -from meetup.models import MeetupLocation +from django.utils import timezone +from meetup.models import Meetup from meetup.permissions import groups_templates, group_permissions -from meetup.utils import (create_groups, assign_permissions, remove_groups, - get_groups) +from meetup.utils import (create_groups, assign_permissions, remove_groups) from users.models import SystersUser @@ -23,29 +23,16 @@ def test_create_groups(self): group_names.append(group.name) self.assertCountEqual(list(expected_group_names), group_names) - meetup_location_groups = Group.objects.filter(name__startswith=name) - self.assertCountEqual(meetup_location_groups, groups) + meetup_groups = Group.objects.filter(name__startswith=name) + self.assertCountEqual(meetup_groups, groups) def test_remove_groups(self): """Test the removal of groups according to a name""" name = "Foo" create_groups(name) remove_groups(name) - meetup_location_groups = Group.objects.filter(name__startswith=name) - self.assertEqual(list(meetup_location_groups), []) - - def test_get_groups(self): - """Test getting groups according to meetup location name""" - groups = get_groups("Foo") - self.assertSequenceEqual(groups, []) - name = "Bar" - create_groups(name) - meetup_location_groups = Group.objects.all() - groups = get_groups("Bar") - self.assertCountEqual(meetup_location_groups, groups) - create_groups("New") - groups = get_groups("Bar") - self.assertCountEqual(meetup_location_groups, groups) + meetup_groups = Group.objects.filter(name__startswith=name) + self.assertEqual(list(meetup_groups), []) def test_assign_permissions(self): """Test assignment of permissions to meetup location groups""" @@ -55,15 +42,20 @@ def test_assign_permissions(self): systers_user = SystersUser.objects.get(user=user) country = Country.objects.create(name='Bar', continent='AS') location = City.objects.create(name='Baz', display_name='Baz', country=country) - meetup_location = MeetupLocation.objects.create( - name="Foo Systers", slug="foo", location=location, - description="It's a test meetup location", sponsors="BarBaz", leader=systers_user) - name = meetup_location.name - groups = create_groups(name) - assign_permissions(meetup_location, groups) + meetup = Meetup.objects.create(title='Foo Bar Baz', slug='foo-bar-baz', + date=timezone.now().date(), + time=timezone.now().time(), + description='This is test Meetup', + meetup_location=location, + created_by=systers_user, + leader=systers_user, + last_updated=timezone.now()) + title = meetup.title + groups = create_groups(title) + assign_permissions(meetup, groups) for key, value in group_permissions.items(): - group = Group.objects.get(name=groups_templates[key].format(name)) + group = Group.objects.get(name=groups_templates[key].format(title)) group_perms = [p.codename for p in list(group.permissions.all())] - group_perms += get_perms(group, meetup_location) + group_perms += get_perms(group, meetup) self.assertCountEqual(group_perms, value) diff --git a/systers_portal/meetup/tests/test_views.py b/systers_portal/meetup/tests/test_views.py index 54527d45..2c1f04da 100644 --- a/systers_portal/meetup/tests/test_views.py +++ b/systers_portal/meetup/tests/test_views.py @@ -1,166 +1,81 @@ +import json from django.contrib.auth.models import User -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase, Client from django.utils import timezone from cities_light.models import City, Country from django.contrib.contenttypes.models import ContentType -from django.core import mail -from meetup.models import (Meetup, MeetupLocation, Rsvp, SupportRequest, RequestMeetupLocation, +from meetup.models import (Meetup, Rsvp, SupportRequest, RequestMeetup) from users.models import SystersUser from common.models import Comment -from rest_framework.test import APITestCase -import json -class MeetupLocationViewBaseTestCase(object): +class MeetupBaseCase: def setUp(self): - self.user = User.objects.create_user(username='foo', password='foobar', - email='user@test.com') - self.systers_user = SystersUser.objects.get(user=self.user) country = Country.objects.create(name='Bar', continent='AS') - self.location = City.objects.create(name='Baz', display_name='Baz', country=country) - self.meetup_location = MeetupLocation.objects.create( - name="Foo Systers", slug="foo", location=self.location, - description="It's a test meetup location", sponsors="BarBaz", leader=self.systers_user) - self.meetup_location.members.add(self.systers_user) - self.meetup_location.moderators.add(self.systers_user) + self.meetup_location = City.objects.create(name='Foo', display_name='Foo', + country=country) + self.user = User.objects.create_superuser(username='foo', email="test@gmail.com", + password='foobar') + self.systers_user = SystersUser.objects.get(user=self.user) self.meetup = Meetup.objects.create(title='Foo Bar Baz', slug='foo-bar-baz', date=timezone.now().date(), time=timezone.now().time(), description='This is test Meetup', meetup_location=self.meetup_location, created_by=self.systers_user, + leader=self.systers_user, last_updated=timezone.now()) -class MeetupLocationAboutViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def test_view_meetup_location_about_view(self): - """Test Meetup Location about view for correct http response""" - url = reverse('about_meetup_location', kwargs={'slug': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, 'meetup/about.html') - self.assertEqual(response.context['meetup_location'], self.meetup_location) - - nonexistent_url = reverse('about_meetup_location', kwargs={'slug': 'bar'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - -class AllUpcomingMeetupsViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class AllUpcomingMeetupsViewTestCase(MeetupBaseCase, TestCase): def test_view_all_upcoming_meetups_list_view(self): """Test All Upcoming Meetups list view for correct http response""" url = reverse('all_upcoming_meetups') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "meetup/list_meetup.html") - self.assertContains(response, "Foo Systers") self.assertContains(response, "Foo Bar Baz") self.assertEqual(len(response.context['object_list']), 1) self.assertEqual(len(response.context['meetup_list']), 1) - - self.meetup_location2 = MeetupLocation.objects.create( - name="Bar Systers", slug="bar", location=self.location, - description="It's a test meetup location", leader=self.systers_user) self.meetup2 = Meetup.objects.create(title='Bar Baz', slug='bazbar', date=(timezone.now() + timezone.timedelta(2)).date(), time=timezone.now().time(), description='This is new test Meetup', - meetup_location=self.meetup_location2, + meetup_location=self.meetup_location, created_by=self.systers_user, + leader=self.systers_user, last_updated=timezone.now()) url = reverse('all_upcoming_meetups') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "meetup/list_meetup.html") - self.assertContains(response, "Foo Systers") - self.assertContains(response, "Bar Systers") self.assertContains(response, "Foo Bar Baz") self.assertContains(response, "Bar Baz") self.assertEqual(len(response.context['object_list']), 2) self.assertEqual(len(response.context['meetup_list']), 2) -class MeetupLocationListViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def test_view_meetup_location_list_view(self): - """Test Meetup Location list view for correct http response, - all meetup locations in a list and all upcoming meetups""" - url = reverse('list_meetup_location') - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "meetup/list_location.html") - self.assertContains(response, "Foo Systers") - self.assertContains(response, "Foo Bar Baz") - self.assertContains(response, "google.maps.Map") - self.assertEqual(len(response.context['object_list']), 1) - self.assertEqual(len(response.context['meetup_list']), 1) - - self.meetup_location2 = MeetupLocation.objects.create( - name="Bar Systers", slug="bar", location=self.location, - description="It's a test meetup location", leader=self.systers_user) - self.meetup2 = Meetup.objects.create(title='Bar Baz', slug='bazbar', - date=(timezone.now() + timezone.timedelta(2)).date(), - time=timezone.now().time(), - description='This is new test Meetup', - meetup_location=self.meetup_location2, - created_by=self.systers_user, - last_updated=timezone.now()) - url = reverse('list_meetup_location') - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "meetup/list_location.html") - self.assertContains(response, "Foo Systers") - self.assertContains(response, "Bar Systers") - self.assertContains(response, "Foo Bar Baz") - self.assertContains(response, "Bar Baz") - self.assertEqual(len(response.context['object_list']), 2) - self.assertEqual(len(response.context['meetup_list']), 2) - self.assertContains(response, "google.maps.Map") - - -class MeetupViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class MeetupViewTestCase(MeetupBaseCase, TestCase): def test_view_meetup(self): """Test Meetup view for correct response""" - url = reverse('view_meetup', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse('view_meetup', kwargs={'slug': 'foo-bar-baz'}) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'meetup/meetup.html') - self.assertEqual(response.context['meetup_location'], self.meetup_location) self.assertEqual(response.context['meetup'], self.meetup) - nonexistent_url = reverse('view_meetup', kwargs={'slug': 'foo1', - 'meetup_slug': 'bazbar'}) + nonexistent_url = reverse('view_meetup', kwargs={'slug': 'bazbar'}) response = self.client.get(nonexistent_url) self.assertEqual(response.status_code, 404) - self.meetup_location2 = MeetupLocation.objects.create( - name="Bar Systers", slug="bar", location=self.location, - description="It's a test meetup location", leader=self.systers_user) - incorrect_pair_url = reverse('view_meetup', kwargs={'slug': 'bar', - 'meetup_slug': 'foo-bar-baz'}) - response = self.client.get(incorrect_pair_url) - self.assertEqual(response.status_code, 404) - -class MeetupLocationMembersViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def test_view_meetup_location_members_view(self): - """Test Meetup Location members view for correct http response""" - url = reverse('members_meetup_location', kwargs={'slug': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, 'meetup/members.html') - - nonexistent_url = reverse('members_meetup_location', kwargs={'slug': 'bar'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - -class AddMeetupViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class AddMeetupViewTestCase(MeetupBaseCase, TestCase): def test_get_add_meetup_view(self): """Test GET request to add a new meetup""" - url = reverse('add_meetup', kwargs={'slug': 'foo'}) + url = reverse('add_meetup') response = self.client.get(url) self.assertEqual(response.status_code, 403) self.client.login(username='foo', password='foobar') @@ -182,7 +97,7 @@ def test_get_add_meetup_view(self): def test_post_add_meetup_view(self): """Test POST request to add a new meetup""" - url = reverse("add_meetup", kwargs={'slug': 'foo'}) + url = reverse("add_meetup") response = self.client.post(url, data={}) self.assertEqual(response.status_code, 403) @@ -190,6 +105,7 @@ def test_post_add_meetup_view(self): date = (timezone.now() + timezone.timedelta(2)).date() time = timezone.now().time() data = {'title': 'BarTest', 'slug': 'bartest', 'date': date, 'time': time, + 'meetup_location': self.meetup_location.id, 'description': "It's a test meetup."} response = self.client.post(url, data=data) self.assertEqual(response.status_code, 302) @@ -199,10 +115,10 @@ def test_post_add_meetup_view(self): self.assertTrue(new_meetup.meetup_location, self.meetup_location) -class RequestMeetupViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class RequestMeetupViewTestCase(MeetupBaseCase, TestCase): def test_get_request_meetup_view(self): """Test GET request to request a new meetup""" - url = reverse('request_meetup', kwargs={'slug': 'foo'}) + url = reverse('request_meetup') response = self.client.get(url) self.assertEqual(response.status_code, 403) self.client.login(username='foo', password='foobar') @@ -212,7 +128,7 @@ def test_get_request_meetup_view(self): def test_post_request_meetup_view(self): """Test POST request to request a new meetup""" - url = reverse("request_meetup", kwargs={'slug': 'foo'}) + url = reverse("request_meetup") response = self.client.post(url, data={}) self.assertEqual(response.status_code, 403) @@ -220,9 +136,9 @@ def test_post_request_meetup_view(self): date = (timezone.now() + timezone.timedelta(2)).date() time = timezone.now().time() data = {'title': 'BarTest', 'slug': 'bartest', 'date': date, 'time': time, + 'meetup_location': self.meetup_location.id, 'description': "It's a test meetup."} - response = self.client.post(url, data=data, created_by=self.systers_user, - meetup_location=self.meetup_location) + response = self.client.post(url, data=data, created_by=self.systers_user) self.assertEqual(response.status_code, 302) new_meetup_request = RequestMeetup.objects.get(slug='bartest') self.assertTrue(new_meetup_request.title, 'BarTest') @@ -230,33 +146,37 @@ def test_post_request_meetup_view(self): self.assertTrue(new_meetup_request.meetup_location, self.meetup_location) -class NewMeetupRequestsListViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class NewMeetupRequestsListViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(NewMeetupRequestsListViewTestCase, self).setUp() self.meetup_request1 = RequestMeetup.objects.create( - title="Bar Talk", slug="bar", date=timezone.now().date(), time=timezone.now().time(), - description="This is a test meetup location request1", created_by=self.systers_user, + title="Bar Talk", slug="bar", date=timezone.now().date(), + time=timezone.now().time(), + description="This is a test meetup meetup_location request1", + created_by=self.systers_user, meetup_location=self.meetup_location) self.meetup_request2 = RequestMeetup.objects.create( - title="Foo Talk", slug="foo", date=timezone.now().date(), time=timezone.now().time(), - description="This is a test meetup location request2", created_by=self.systers_user, + title="Foo Talk", slug="foo", date=timezone.now().date(), + time=timezone.now().time(), + description="This is a test meetup meetup_location request2", + created_by=self.systers_user, meetup_location=self.meetup_location) self.password = 'foobar' self.user2 = User.objects.create(username='foobar', password=self.password, email='foo@test.com') self.systers_user2 = SystersUser.objects.get(user=self.user2) - def test_view_new_meetup_location_requests_list_view(self): + def test_view_new_meetup_meetup_location_requests_list_view(self): """Test Meetup Requests list view for correct http response and all meetup requests in a list""" - url = reverse('new_meetup_requests', kwargs={'slug': 'foo'}) + url = reverse('new_meetup_requests') response = self.client.get(url) self.assertEqual(response.status_code, 403) # Testing after logggin in - normal user self.client.login(username='foobar', password='foobar') response = self.client.get(url) self.assertEqual(response.status_code, 403) - # Testing after logging in - Organizer of the Meetup Location + # Testing after logging in - Organizer of the Meetup meetup_location self.client.login(username='foo', password='foobar') response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -268,12 +188,14 @@ def test_view_new_meetup_location_requests_list_view(self): self.assertContains(response, "Requested by") -class ViewMeetupRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class ViewMeetupRequestViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(ViewMeetupRequestViewTestCase, self).setUp() self.meetup_request = RequestMeetup.objects.create( - title="Foo Talk", slug="bar", date=timezone.now().date(), time=timezone.now().time(), - description="This is a test meetup location request", created_by=self.systers_user, + title="Foo Talk", slug="bar", date=timezone.now().date(), + time=timezone.now().time(), + description="This is a test meetup meetup_location request", + created_by=self.systers_user, meetup_location=self.meetup_location) self.password = 'foobar' self.user2 = User.objects.create(username='foobar', password=self.password, @@ -283,7 +205,7 @@ def setUp(self): def test_view_meetup_request_view(self): """Test Meetup Request view for correct response""" # Test without logging in - url = reverse('view_meetup_request', kwargs={'slug': 'foo', 'meetup_slug': 'bar'}) + url = reverse('view_meetup_request', kwargs={'meetup_slug': 'bar'}) response = self.client.get(url) self.assertEqual(response.status_code, 403) # Test after logging in - normal user @@ -300,12 +222,14 @@ def test_view_meetup_request_view(self): response.context['meetup_request'], self.meetup_request) -class ApproveRequestMeetupViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class ApproveRequestMeetupViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(ApproveRequestMeetupViewTestCase, self).setUp() self.meetup_request = RequestMeetup.objects.create( - title="Foo Talk", slug="bar", date=timezone.now().date(), time=timezone.now().time(), - description="This is a test meetup location request", created_by=self.systers_user, + title="Foo Talk", slug="bar", date=timezone.now().date(), + time=timezone.now().time(), + description="This is a test meetup meetup_location request", + created_by=self.systers_user, meetup_location=self.meetup_location) self.password = 'foobar' self.user2 = User.objects.create(username='foobar', password=self.password, @@ -314,7 +238,7 @@ def setUp(self): def test_approve_request_meetup_view_base(self): url = reverse('approve_meetup_request', - kwargs={'meetup_slug': 'bar', 'slug': 'foo'}) + kwargs={'meetup_slug': 'bar'}) # Test without logging in response = self.client.get(url) self.assertEqual(response.status_code, 403) @@ -326,36 +250,39 @@ def test_approve_request_meetup_view_base(self): self.client.login(username='foo', password='foobar') response = self.client.get(url) self.assertEqual(response.status_code, 302) - self.assertTrue(response.url.endswith('meetup/foo/bar/')) + self.assertTrue(response.url.endswith('meetup/bar/')) # Test for non existent url nonexistent_url = reverse('approve_meetup_request', - kwargs={'slug': 'foo', 'meetup_slug': 'carr'}) + kwargs={'meetup_slug': 'carr'}) response = self.client.get(nonexistent_url) self.assertEqual(response.status_code, 404) def test_approve_request_meetup_view_slug(self): - """Test if slug already exists in Meetup Location objects, redirect to edit page.""" + """Test if slug already exists in Meetup meetup_location objects, redirect to edit page.""" url = reverse('approve_meetup_request', - kwargs={'meetup_slug': 'bar', 'slug': 'foo'}) + kwargs={'meetup_slug': 'bar'}) Meetup.objects.create(title='Foo Bar Baz', slug='bar', date=timezone.now().date(), time=timezone.now().time(), description='This is test Meetup', meetup_location=self.meetup_location, created_by=self.systers_user, + leader=self.systers_user, last_updated=timezone.now()) self.client.login(username='foo', password='foobar') response = self.client.get(url) self.assertEqual(response.status_code, 302) - self.assertTrue(response.url.endswith('meetup/foo/view_meetup_requests/')) + self.assertTrue(response.url.endswith('meetup/view_meetup_requests/')) -class RejectMeetupRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class RejectMeetupRequestViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(RejectMeetupRequestViewTestCase, self).setUp() self.meetup_request = RequestMeetup.objects.create( - title="Foo Talk", slug="bar", date=timezone.now().date(), time=timezone.now().time(), - description="This is a test meetup request", created_by=self.systers_user, + title="Foo Talk", slug="bar", date=timezone.now().date(), + time=timezone.now().time(), + description="This is a test meetup request", + created_by=self.systers_user, meetup_location=self.meetup_location) self.password = 'foobar' self.user2 = User.objects.create(username='foobar', password=self.password, @@ -363,7 +290,7 @@ def setUp(self): self.systers_user2 = SystersUser.objects.get(user=self.user2) def test_get_reject_request_meetup_view(self): - url = reverse('reject_meetup_request', kwargs={'slug': 'foo', 'meetup_slug': 'bar'}) + url = reverse('reject_meetup_request', kwargs={'meetup_slug': 'bar'}) # Test without logging in response = self.client.get(url) self.assertEqual(response.status_code, 403) @@ -379,12 +306,12 @@ def test_get_reject_request_meetup_view(self): response, "meetup/confirm_reject_request_meetup.html") # Test for non existent url nonexistent_url = reverse('reject_meetup_request', - kwargs={'slug': 'foo', 'meetup_slug': 'barr'}) + kwargs={'meetup_slug': 'barr'}) response = self.client.get(nonexistent_url) self.assertEqual(response.status_code, 404) - def test_post_reject_request_meetup_location_view(self): - url = reverse('reject_meetup_request', kwargs={'slug': 'foo', 'meetup_slug': 'bar'}) + def test_post_reject_request_meetup_meetup_location_view(self): + url = reverse('reject_meetup_request', kwargs={'meetup_slug': 'bar'}) # Test without logging in response = self.client.post(url) self.assertEqual(response.status_code, 403) @@ -399,12 +326,12 @@ def test_post_reject_request_meetup_location_view(self): self.assertTrue(response.url.endswith('view_meetup_requests/')) # Test non existent url nonexistent_url = reverse('reject_meetup_request', - kwargs={'slug': 'foo', 'meetup_slug': 'barr'}) + kwargs={'meetup_slug': 'barr'}) response = self.client.post(nonexistent_url) self.assertEqual(response.status_code, 404) -class DeleteMeetupViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class DeleteMeetupViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(DeleteMeetupViewTestCase, self).setUp() self.meetup2 = Meetup.objects.create(title='Fooba', slug='fooba', @@ -413,12 +340,13 @@ def setUp(self): description='This is test Meetup', meetup_location=self.meetup_location, created_by=self.systers_user, + leader=self.systers_user, last_updated=timezone.now()) self.client = Client() def test_get_delete_meetup_view(self): """Test GET to confirm deletion of meetup""" - url = reverse("delete_meetup", kwargs={'slug': 'foo', 'meetup_slug': 'fooba'}) + url = reverse("delete_meetup", kwargs={'meetup_slug': 'fooba'}) response = self.client.get(url) self.assertEqual(response.status_code, 403) @@ -429,7 +357,7 @@ def test_get_delete_meetup_view(self): def test_post_delete_meetup_view(self): """Test POST to delete a meetup""" - url = reverse("delete_meetup", kwargs={'slug': 'foo', 'meetup_slug': 'fooba'}) + url = reverse("delete_meetup", kwargs={'meetup_slug': 'fooba'}) response = self.client.post(url) self.assertEqual(response.status_code, 403) @@ -438,18 +366,18 @@ def test_post_delete_meetup_view(self): self.assertEqual(response.status_code, 302) # One meetup deleted, another meetup left initialized in - # MeetupLocationViewBaseTestCase + # Meetupmeetup_locationViewBaseTestCase self.assertSequenceEqual(Meetup.objects.all(), [self.meetup]) -class EditMeetupView(MeetupLocationViewBaseTestCase, TestCase): +class EditMeetupView(MeetupBaseCase, TestCase): def test_get_edit_meetup_view(self): """Test GET edit meetup""" - wrong_url = reverse("edit_meetup", kwargs={'slug': 'foo', 'meetup_slug': 'foo'}) + wrong_url = reverse("edit_meetup", kwargs={'meetup_slug': 'foo'}) response = self.client.get(wrong_url) self.assertEqual(response.status_code, 403) - url = reverse("edit_meetup", kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse("edit_meetup", kwargs={'meetup_slug': 'foo-bar-baz'}) response = self.client.get(url) self.assertEqual(response.status_code, 403) self.client.login(username='foo', password='foobar') @@ -471,25 +399,26 @@ def test_get_edit_meetup_view(self): def test_post_edit_meetup_view(self): """Test POST edit meetup""" - wrong_url = reverse("edit_meetup", kwargs={'slug': 'foo', 'meetup_slug': 'foo'}) + wrong_url = reverse("edit_meetup", kwargs={'meetup_slug': 'foo'}) response = self.client.post(wrong_url) self.assertEqual(response.status_code, 403) - url = reverse("edit_meetup", kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse("edit_meetup", kwargs={'meetup_slug': 'foo-bar-baz'}) response = self.client.post(url) self.assertEqual(response.status_code, 403) date = (timezone.now() + timezone.timedelta(2)).date() time = timezone.now().time() data = {'title': 'BarTes', 'slug': 'bartes', 'date': date, 'time': time, + 'meetup_location': self.meetup_location, 'description': "It's a edit test meetup."} self.client.login(username='foo', password='foobar') response = self.client.post(url, data=data) self.assertEqual(response.status_code, 302) - self.assertTrue(response.url.endswith('/meetup/foo/bartes/')) + self.assertTrue(response.url.endswith('/meetup/bartes/')) -class UpcomingMeetupsViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class UpcomingMeetupsViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(UpcomingMeetupsViewTestCase, self).setUp() self.meetup2 = Meetup.objects.create(title='Bar Baz', slug='bazbar', @@ -498,12 +427,13 @@ def setUp(self): description='This is new test Meetup', meetup_location=self.meetup_location, created_by=self.systers_user, + leader=self.systers_user, last_updated=timezone.now()) def test_view_upcoming_meetup_list_view(self): """Test Upcoming Meetup list view for correct http response and all upcoming meetups in a list""" - url = reverse('upcoming_meetups', kwargs={'slug': 'foo'}) + url = reverse('upcoming_meetups') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "meetup/upcoming_meetups.html") @@ -512,7 +442,7 @@ def test_view_upcoming_meetup_list_view(self): self.assertEqual(len(response.context['meetup_list']), 2) -class PastMeetupListViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class PastMeetupListViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(PastMeetupListViewTestCase, self).setUp() # a future meetup. This should not show up under 'past meetups'. @@ -522,6 +452,7 @@ def setUp(self): description='This is new test Meetup', meetup_location=self.meetup_location, created_by=self.systers_user, + leader=self.systers_user, last_updated=timezone.now()) # a past meetup. This should show up under 'past meetups'. self.meetup3 = Meetup.objects.create(title='Foo Baz', slug='foobar', @@ -530,710 +461,24 @@ def setUp(self): description='This is new test Meetup', meetup_location=self.meetup_location, created_by=self.systers_user, + leader=self.systers_user, last_updated=timezone.now()) def test_view_past_meetup_list_view(self): """Test Past Meetup list view for correct http response and all past meetups in a list""" - url = reverse('past_meetups', kwargs={'slug': 'foo'}) + url = reverse('past_meetups') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "meetup/past_meetups.html") self.assertEqual(len(response.context['meetup_list']), 1) -class MeetupLocationSponsorsViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def test_view_meetup_location_sponsors_view(self): - """Test Meetup Location sponsors view for correct http response""" - url = reverse('sponsors_meetup_location', kwargs={'slug': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "meetup/sponsors.html") - self.assertEqual(response.context['meetup_location'], self.meetup_location) - - nonexistent_url = reverse('sponsors_meetup_location', kwargs={'slug': 'bar'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - -class RemoveMeetupLocationMemberViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(RemoveMeetupLocationMemberViewTestCase, self).setUp() - self.user2 = User.objects.create_user(username='baz', password='bazbar') - self.systers_user2 = SystersUser.objects.get(user=self.user2) - self.meetup_location.members.add(self.systers_user2) - self.meetup_location.moderators.add(self.systers_user2) - self.user3 = User.objects.create_user(username='bar', password='barbar') - self.systers_user3 = SystersUser.objects.get(user=self.user3) - self.meetup_location.members.add(self.systers_user3) - - def test_view_remove_meetup_location_member_view(self): - """ - Test remove Meetup Location member view for 3 cases: - * removing only a member - * removing one of two members who are moderators - * removing member who is the only moderator - """ - url = reverse("remove_member_meetup_location", - kwargs={'slug': 'foo', 'username': 'bar'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - nonexistent_url = reverse("remove_member_meetup_location", - kwargs={'slug': 'foo', 'username': 'barbaz'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - url = reverse("remove_member_meetup_location", - kwargs={'slug': 'foo', 'username': 'bar'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/members/') - self.assertEqual(len(self.meetup_location.members.all()), 2) - - url = reverse("remove_member_meetup_location", - kwargs={'slug': 'foo', 'username': 'baz'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/members/') - self.assertEqual(len(self.meetup_location.members.all()), 1) - self.assertEqual(len(self.meetup_location.moderators.all()), 1) - - url = reverse("remove_member_meetup_location", - kwargs={'slug': 'foo', 'username': 'foo'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/members/') - self.assertEqual(len(self.meetup_location.members.all()), 1) - self.assertEqual(len(self.meetup_location.moderators.all()), 1) - - -class AddMeetupLocationMemberViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(AddMeetupLocationMemberViewTestCase, self).setUp() - self.user2 = User.objects.create_user(username='baz', password='bazbar') - self.systers_user2 = SystersUser.objects.get(user=self.user2) - - def test_get_add_meetup_location_member_view(self): - url = reverse("add_member_meetup_location", kwargs={'slug': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - for message in response.context['messages']: - self.assertEqual(message.tags, "success") - self.assertTrue( - 'Successfully' - in message.message) - - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - for message in response.context['messages']: - self.assertEqual(message.tags, "error") - self.assertTrue( - 'Something went wrong. Please try again' - in message.message) - self.assertTemplateUsed(response, 'meetup/add_member.html') - - def test_post_add_meetup_location_member_view(self): - url = reverse("add_member_meetup_location", kwargs={'slug': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - username = self.user2.get_username() - data = {'username': username} - self.client.login(username='foo', password='foobar') - response = self.client.post(url, data=data) - self.assertTrue(response.url.endswith('/meetup/foo/members/')) - self.assertEqual(response.status_code, 302) - - -class RemoveMeetupLocationModeratorViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(RemoveMeetupLocationModeratorViewTestCase, self).setUp() - self.user2 = User.objects.create_user(username='baz', password='bazbar') - self.systers_user2 = SystersUser.objects.get(user=self.user2) - self.meetup_location.members.add(self.systers_user2) - self.meetup_location.moderators.add(self.systers_user2) - - def test_view_remove_meetup_location_moderator_view(self): - """ - Test remove Meetup Location moderator view for 2 cases: - * remove one of two moderators - * remove the only moderator - """ - url = reverse("remove_moderator_meetup_location", - kwargs={'slug': 'foo', 'username': 'baz'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - nonexistent_url = reverse("remove_moderator_meetup_location", - kwargs={'slug': 'foo', 'username': 'barbaz'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - url = reverse("remove_moderator_meetup_location", - kwargs={'slug': 'foo', 'username': 'baz'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/members/') - self.assertEqual(len(self.meetup_location.members.all()), 2) - self.assertEqual(len(self.meetup_location.moderators.all()), 1) - - url = reverse("remove_moderator_meetup_location", - kwargs={'slug': 'foo', 'username': 'foo'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/members/') - self.assertEqual(len(self.meetup_location.members.all()), 2) - self.assertEqual(len(self.meetup_location.moderators.all()), 1) - - -class MakeMeetupLocationModeratorViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(MakeMeetupLocationModeratorViewTestCase, self).setUp() - self.password = 'bazbar' - self.user2 = User.objects.create_user(username='baz', password=self.password, - email='user2@test.com') - self.systers_user2 = SystersUser.objects.get(user=self.user2) - self.meetup_location.members.add(self.systers_user2) - - def test_view_make_meetup_location_moderator_view(self): - """Test make Meetup Location moderator view for correct http response""" - url = reverse("make_moderator_meetup_location", - kwargs={'slug': 'foo', 'username': 'baz'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - nonexistent_url = reverse("make_moderator_meetup_location", - kwargs={'slug': 'foo', 'username': 'barbaz'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - url = reverse("make_moderator_meetup_location", - kwargs={'slug': 'foo', 'username': 'baz'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/members/') - self.assertEqual(len(self.meetup_location.members.all()), 2) - self.assertEqual(len(self.meetup_location.moderators.all()), 2) - self.assertEqual(len(mail.outbox), 1) - self.assertIn(self.user2.email, mail.outbox[0].to) - self.assertIn('Made moderator', mail.outbox[0].subject) - - -class JoinMeetupLocationViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(JoinMeetupLocationViewTestCase, self).setUp() - self.user2 = User.objects.create_user(username='baz', password='bazbar', - email='user2@test.com') - self.systers_user2 = SystersUser.objects.get(user=self.user2) - self.meetup_location.join_requests.add(self.systers_user2) - self.password = 'barbar' - self.user3 = User.objects.create_user(username='bar', password=self.password, - email='user2@test.com') - self.systers_user3 = SystersUser.objects.get(user=self.user3) - - def test_view_join_meetup_location_view(self): - """ - Test join meetup location view for three cases: - * User who is joining meetup location - * User who has already requested to join - * User who is already a member - """ - url = reverse('join_meetup_location', kwargs={'slug': 'foo', 'username': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - wrong_url = reverse('join_meetup_location', kwargs={'slug': 'foo', 'username': 'foba'}) - response = self.client.get(wrong_url) - self.assertEqual(response.status_code, 404) - - url = reverse('join_meetup_location', kwargs={'slug': 'foo', 'username': 'bar'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/about/') - self.assertEqual(len(self.meetup_location.join_requests.all()), 2) - for message in response.context['messages']: - self.assertEqual(message.tags, "success") - self.assertTrue( - 'Your request to join meetup location Foo Systers has been sent.' - in message.message) - self.assertEqual(len(mail.outbox), 1) - self.assertIn(self.user.email, mail.outbox[0].to) - self.assertIn('New Join Request', mail.outbox[0].subject) - - url = reverse('join_meetup_location', kwargs={'slug': 'foo', 'username': 'baz'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/about/') - self.assertEqual(len(self.meetup_location.join_requests.all()), 2) - for message in response.context['messages']: - self.assertEqual(message.tags, "warning") - self.assertTrue( - 'You have already requested to join meetup location Foo Systers.' - in message.message) - - url = reverse('join_meetup_location', kwargs={'slug': 'foo', 'username': 'foo'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/about/') - self.assertEqual(len(self.meetup_location.join_requests.all()), 2) - for message in response.context['messages']: - self.assertEqual(message.tags, "warning") - self.assertTrue( - 'You are already a member of meetup location Foo Systers.' - in message.message) - - -class MeetupLocationJoinRequestsViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(MeetupLocationJoinRequestsViewTestCase, self).setUp() - self.user2 = User.objects.create_user(username='baz', password='bazbar') - self.systers_user2 = SystersUser.objects.get(user=self.user2) - self.meetup_location.join_requests.add(self.systers_user2) - - def test_view_meetup_location_join_requests_view(self): - """Test meetup location join requests view for correct http response""" - url = reverse('join_requests_meetup_location', kwargs={'slug': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 302) - - self.client.login(username='foo', password='foobar') - nonexistent_url = reverse('join_requests_meetup_location', kwargs={'slug': 'baaa'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - url = reverse('join_requests_meetup_location', kwargs={'slug': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, "meetup/join_requests.html") - self.assertEqual(len(response.context['requests']), 1) - - -class ApproveMeetupLocationJoinRequestsViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(ApproveMeetupLocationJoinRequestsViewTestCase, self).setUp() - self.user2 = User.objects.create_user(username='baz', password='bazbar', - email='user2@test.com') - self.systers_user2 = SystersUser.objects.get(user=self.user2) - self.meetup_location.join_requests.add(self.systers_user2) - - def test_view_approve_meetup_location_join_requests_view(self): - """Test approve meetup location join requests view for correct http response""" - url = reverse('approve_join_request_meetup_location', - kwargs={'slug': 'foo', 'username': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - nonexistent_url = reverse('approve_join_request_meetup_location', - kwargs={'slug': 'foo', 'username': 'foba'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - url = reverse('approve_join_request_meetup_location', - kwargs={'slug': 'foo', 'username': 'baz'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/join_requests/') - self.assertEqual(len(self.meetup_location.join_requests.all()), 0) - self.assertEqual(len(self.meetup_location.members.all()), 2) - self.assertEqual(len(mail.outbox), 1) - self.assertIn(self.user2.email, mail.outbox[0].to) - self.assertIn('Joined Meetup Location', mail.outbox[0].subject) - - -class RejectMeetupLocationJoinRequestsViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(RejectMeetupLocationJoinRequestsViewTestCase, self).setUp() - self.user2 = User.objects.create_user(username='baz', password='bazbar') - self.systers_user2 = SystersUser.objects.get(user=self.user2) - self.meetup_location.join_requests.add(self.systers_user2) - - def test_view_reject_meetup_location_join_requests_view(self): - """Test reject meetup location join requests view for correct http response""" - url = reverse('reject_join_request_meetup_location', - kwargs={'slug': 'foo', 'username': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - nonexistent_url = reverse('reject_join_request_meetup_location', - kwargs={'slug': 'foo', 'username': 'foba'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - url = reverse('reject_join_request_meetup_location', - kwargs={'slug': 'foo', 'username': 'baz'}) - response = self.client.get(url, follow=True) - self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/join_requests/') - self.assertEqual(len(self.meetup_location.join_requests.all()), 0) - self.assertEqual(len(self.meetup_location.members.all()), 1) - - -class AddMeetupLocationViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def test_get_add_meetup_location_view(self): - """Test GET request to add a new meetup location""" - url = reverse('add_meetup_location') - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - self.client.login(username='foo', password='foobar') - - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - for message in response.context['messages']: - self.assertEqual(message.tags, "success") - self.assertTrue( - 'Successfully' - in message.message) - - self.assertEqual(response.status_code, 200) - for message in response.context['messages']: - self.assertEqual(message.tags, "error") - self.assertTrue( - 'Something went wrong. Please try again' - in message.message) - self.assertTemplateUsed(response, 'meetup/add_meetup_location.html') - - def test_post_add_meetup_location_view(self): - """Test POST request to add a new meetup location""" - url = reverse('add_meetup_location') - response = self.client.post(url, data={}) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - url = reverse('add_meetup_location') - data = {'name': 'Bar Systers', 'slug': 'bar', 'location': self.location.id, - 'description': "It's a new meetup location", 'sponsors': 'BaaBaa'} - response = self.client.post(url, data=data, user=self.systers_user) - self.assertEqual(response.status_code, 302) - new_meetup_location = MeetupLocation.objects.get(slug='bar') - self.assertTrue(new_meetup_location.name, 'Bar Systers') - - -class RequestMeetupLocationViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def test_get_add_meetup_location_view(self): - """Test GET request to add a new meetup location""" - url = reverse('request_meetup_location') - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed( - response, 'meetup/request_new_meetup_location.html') - - def test_post_add_meetup_location_view(self): - """Test POST request to add a new meetup location""" - url = reverse('request_meetup_location') - response = self.client.post(url, data={}) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - data = {'name': 'Bar Systers', 'slug': 'bar', 'location': self.location.id, - 'description': "It's a new meetup location"} - response = self.client.post(url, data=data, user=self.systers_user) - self.assertEqual(response.status_code, 302) - new_meetup_location_request = RequestMeetupLocation.objects.get( - slug='bar') - self.assertTrue(new_meetup_location_request.name, 'Bar Systers') - - -class NewMeetupLocationRequestsListViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(NewMeetupLocationRequestsListViewTestCase, self).setUp() - self.meetup_location_request1 = RequestMeetupLocation.objects.create( - name="Bar Systers", slug="bar", location=self.location, - description="This is a test meetup location request1", user=self.systers_user) - self.meetup_location_request2 = RequestMeetupLocation.objects.create( - name="Foo Systers", slug="foo", location=self.location, - description="This is a test meetup location request2", user=self.systers_user) - self.staff_user = User.objects.create_superuser(username='foobar', password='foobar', - email='foobar@test.com') - self.staff_systers_user = SystersUser.objects.get(user=self.staff_user) - - def test_view_new_meetup_location_requests_list_view(self): - """Test Meetup Location Requests list view for correct http response and - all meetup location requests in a list""" - url = reverse('new_meetup_location_requests') - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - # Testing after logggin in - normal user - self.client.login(username='foo', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - # Testing after logging in - staff user - self.client.login(username='foobar', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed( - response, "meetup/new_meetup_location_requests.html") - self.assertContains(response, "Foo Systers") - self.assertSequenceEqual(RequestMeetupLocation.objects.filter( - is_approved=False), [self.meetup_location_request1, self.meetup_location_request2]) - self.assertContains(response, "Requested by") - - -class ViewMeetupLocationRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(ViewMeetupLocationRequestViewTestCase, self).setUp() - self.meetup_location_request = RequestMeetupLocation.objects.create( - name="Bar Systers", slug="bar", location=self.location, - description="This is a test meetup location request", - user=self.systers_user) - self.staff_user = User.objects.create_superuser(username='foobar', password='foobar', - email='foobar@test.com') - self.staff_systers_user = SystersUser.objects.get(user=self.staff_user) - - def test_view_support_request_view(self): - """Test Meetup Location Request view for correct response""" - # Test without logging in - url = reverse('view_meetup_location_request', kwargs={'slug': 'bar'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - # Test after logging in - self.client.login(username='foo', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foobar', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed( - response, 'meetup/view_new_meetup_location_request.html') - self.assertEqual( - response.context['meetup_location_request'], self.meetup_location_request) - - -class ApproveRequestMeetupLocationViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(ApproveRequestMeetupLocationViewTestCase, self).setUp() - self.meetup_location_request = RequestMeetupLocation.objects.create( - name="Bar Systers", slug="bar", location=self.location, - description="This is a test meetup location request", - user=self.systers_user) - self.staff_user = User.objects.create_superuser(username='foobar', password='foobar', - email='foobar@test.com') - self.staff_systers_user = SystersUser.objects.get(user=self.staff_user) - country = Country.objects.create(name='Barbar', continent='AS') - self.location2 = City.objects.create( - name='BazBaz', display_name='Bazz', country=country) - - def test_approve_request_meetup_location_view_base(self): - url = reverse('approve_meetup_location_request', - kwargs={'slug': 'bar'}) - # Test without logging in - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - # Test logging in, normal user - self.client.login(username='foo', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - # Test if accessed by a superuser - self.client.login(username='foobar', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 302) - self.assertTrue(response.url.endswith('meetup/bar/about/')) - # Test for non existent url - nonexistent_url = reverse('approve_meetup_location_request', - kwargs={'slug': 'foo'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - def test_approve_request_meetup_location_view_name(self): - # Test if name of request already exists in Meetup Location objects, redirect to edit page. - url = reverse('approve_meetup_location_request', - kwargs={'slug': 'bar'}) - MeetupLocation.objects.create( - name="Bar Systers", slug="fooo", location=self.location2, - description="It's a test meetup location", sponsors="BarBaz", - leader=self.staff_systers_user) - self.client.login(username='foobar', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 302) - self.assertTrue(response.url.endswith('view-requests/')) - - def test_approve_request_meetup_location_view_slug(self): - """Test if slug already exists in Meetup Location objects, redirect to edit page.""" - url = reverse('approve_meetup_location_request', - kwargs={'slug': 'bar'}) - MeetupLocation.objects.create( - name="Fooo Systers", slug="bar", location=self.location2, - description="It's a test meetup location", sponsors="BarBaz", - leader=self.staff_systers_user) - self.client.login(username='foobar', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 302) - self.assertTrue(response.url.endswith('view-requests/')) - - def test_approve_request_meetup_location_view_location(self): - """Test if slug already exists in Meetup Location objects, redirect to edit page.""" - url = reverse('approve_meetup_location_request', - kwargs={'slug': 'bar'}) - MeetupLocation.objects.create( - name="Fooo Systers", slug="fooo", location=self.location, - description="It's a test meetup location", sponsors="BarBaz", - leader=self.staff_systers_user) - self.client.login(username='foobar', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 302) - self.assertTrue(response.url.endswith('meetup/bar/about/')) - - -class RejectMeetupLocationRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(RejectMeetupLocationRequestViewTestCase, self).setUp() - self.meetup_location_request = RequestMeetupLocation.objects.create( - name="Bar Systers", slug="bar", location=self.location, - description="This is a test meetup location request", - user=self.systers_user) - self.staff_user = User.objects.create_superuser(username='foobar', password='foobar', - email='foobar@test.com') - self.staff_systers_user = SystersUser.objects.get(user=self.staff_user) - - def test_get_reject_request_meetup_location_view(self): - url = reverse('reject_meetup_location_request', kwargs={'slug': 'bar'}) - # Test without logging in - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - # Test logging in, normal user - self.client.login(username='foo', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - # Test if accessed by a superuser - self.client.login(username='foobar', password='foobar') - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed( - response, "meetup/confirm_reject_request_meetup_location.html") - # Test for non existent url - nonexistent_url = reverse('reject_meetup_location_request', - kwargs={'slug': 'foo'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - def test_post_reject_request_meetup_location_view(self): - url = reverse('reject_meetup_location_request', kwargs={'slug': 'bar'}) - # Test without logging in - response = self.client.post(url) - self.assertEqual(response.status_code, 403) - # Test logging in, normal user - self.client.login(username='foo', password='foobar') - response = self.client.post(url) - self.assertEqual(response.status_code, 403) - # Test if superuser posts - self.client.login(username='foobar', password='foobar') - response = self.client.post(url) - self.assertEqual(response.status_code, 302) - self.assertTrue(response.url.endswith('view-requests/')) - # Test non existent url - nonexistent_url = reverse('reject_meetup_location_request', - kwargs={'slug': 'foo'}) - response = self.client.post(nonexistent_url) - self.assertEqual(response.status_code, 404) - - -class EditMeetupLocationViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def test_get_edit_meetup_location_view(self): - """Test GET request to edit meetup location""" - url = reverse("edit_meetup_location", kwargs={'slug': 'foo'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - nonexistent_url = reverse("edit_meetup_location", kwargs={'slug': 'bar'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - response = self.client.get(url) - - self.assertEqual(response.status_code, 200) - for message in response.context['messages']: - self.assertEqual(message.tags, "success") - self.assertTrue( - 'Successfully' - in message.message) - - self.assertEqual(response.status_code, 200) - for message in response.context['messages']: - self.assertEqual(message.tags, "error") - self.assertTrue( - 'Something went wrong. Please try again' - in message.message) - self.assertTemplateUsed(response, 'meetup/edit_meetup_location.html') - - def test_post_edit_meetup_view(self): - """Test POST request to edit meetup location""" - url = reverse("edit_meetup_location", kwargs={'slug': 'foo'}) - response = self.client.post(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - nonexistent_url = reverse("edit_meetup_location", kwargs={'slug': 'bar'}) - response = self.client.post(nonexistent_url) - self.assertEqual(response.status_code, 404) - - data = {'name': 'Bar Systers', 'slug': 'foo', 'location': self.location.id, - 'description': "It's an edited meetup location", 'sponsors': 'BlackSheep'} - response = self.client.post(url, data=data) - self.assertEqual(response.status_code, 302) - self.assertTrue(response.url.endswith('/meetup/foo/about/')) - - -class DeleteMeetupLocationViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(DeleteMeetupLocationViewTestCase, self).setUp() - self.meetup_location2 = MeetupLocation.objects.create( - name="Bar Systers", slug="bar", location=self.location, - description="It's another test meetup location", sponsors="BarBaz", - leader=self.systers_user) - - def test_get_delete_meetup_location_view(self): - """Test GET to confirm deletion of meetup location""" - url = reverse("delete_meetup_location", kwargs={'slug': 'bar'}) - response = self.client.get(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - nonexistent_url = reverse("delete_meetup_location", kwargs={'slug': 'baz'}) - response = self.client.get(nonexistent_url) - self.assertEqual(response.status_code, 404) - - response = self.client.get(url) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, 'meetup/meetup_location_confirm_delete.html') - - def test_post_delete_meetup_location_view(self): - """Test POST to delete meetup location""" - url = reverse("delete_meetup_location", kwargs={'slug': 'bar'}) - response = self.client.post(url) - self.assertEqual(response.status_code, 403) - - self.client.login(username='foo', password='foobar') - nonexistent_url = reverse("delete_meetup_location", kwargs={'slug': 'baz'}) - response = self.client.post(nonexistent_url) - self.assertEqual(response.status_code, 404) - - response = self.client.post(url) - self.assertEqual(response.status_code, 302) - self.assertTrue(response.url.endswith('/meetup/locations/')) - self.assertSequenceEqual(MeetupLocation.objects.all(), [self.meetup_location]) - - -class AddMeetupCommentViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class AddMeetupCommentViewTestCase(MeetupBaseCase, TestCase): def test_get_add_meetup_comment_view(self): """Test GET request to add a comment to a meetup""" self.client.login(username='foo', password='foobar') - url = reverse('add_meetup_comment', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse('add_meetup_comment', kwargs={'meetup_slug': 'foo-bar-baz'}) response = self.client.get(url) self.assertEqual(response.status_code, 200) for message in response.context['messages']: @@ -1253,7 +498,7 @@ def test_get_add_meetup_comment_view(self): def test_post_add_meetup_comment_view(self): """Test POST request to add a comment to a meetup""" self.client.login(username='foo', password='foobar') - url = reverse("add_meetup_comment", kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse("add_meetup_comment", kwargs={'meetup_slug': 'foo-bar-baz'}) data = {'body': 'This is a test comment'} response = self.client.post(url, data=data) @@ -1265,7 +510,7 @@ def test_post_add_meetup_comment_view(self): self.assertEqual(comments[0].content_object, self.meetup) -class EditMeetupCommentViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class EditMeetupCommentViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(EditMeetupCommentViewTestCase, self).setUp() self.user2 = User.objects.create_user(username='baz', password='bazbar') @@ -1284,13 +529,13 @@ def setUp(self): def test_get_edit_meetup_comment_view(self): """Test GET request to edit a comment to a meetup""" self.client.login(username='foo', password='foobar') - url = reverse('edit_meetup_comment', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'comment_pk': self.comment2.id}) + url = reverse('edit_meetup_comment', kwargs={'meetup_slug': 'foo-bar-baz', + 'comment_pk': self.comment2.id}) response = self.client.get(url) self.assertEqual(response.status_code, 403) - url = reverse('edit_meetup_comment', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'comment_pk': self.comment.id}) + url = reverse('edit_meetup_comment', kwargs={'meetup_slug': 'foo-bar-baz', + 'comment_pk': self.comment.id}) response = self.client.get(url) self.assertEqual(response.status_code, 200) for message in response.context['messages']: @@ -1310,8 +555,8 @@ def test_get_edit_meetup_comment_view(self): def test_post_edit_meetup_comment_view(self): """Test POST request to edit a comment to a meetup""" self.client.login(username='foo', password='foobar') - url = reverse("edit_meetup_comment", kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'comment_pk': self.comment.id}) + url = reverse("edit_meetup_comment", kwargs={'meetup_slug': 'foo-bar-baz', + 'comment_pk': self.comment.id}) data = {'body': 'This is an edited test comment'} response = self.client.post(url, data=data) @@ -1324,7 +569,7 @@ def test_post_edit_meetup_comment_view(self): self.assertEqual(comment.content_object, self.meetup) -class DeleteMeetupCommentViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class DeleteMeetupCommentViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(DeleteMeetupCommentViewTestCase, self).setUp() self.user2 = User.objects.create_user(username='baz', password='bazbar') @@ -1343,13 +588,13 @@ def setUp(self): def test_get_delete_meetup_comment_view(self): """Test GET request to delete a comment to a meetup""" self.client.login(username='foo', password='foobar') - url = reverse('delete_meetup_comment', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'comment_pk': self.comment2.id}) + url = reverse('delete_meetup_comment', kwargs={'meetup_slug': 'foo-bar-baz', + 'comment_pk': self.comment2.id}) response = self.client.get(url) self.assertEqual(response.status_code, 403) - url = reverse('delete_meetup_comment', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'comment_pk': self.comment.id}) + url = reverse('delete_meetup_comment', kwargs={'meetup_slug': 'foo-bar-baz', + 'comment_pk': self.comment.id}) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, "Confirm to delete") @@ -1357,8 +602,8 @@ def test_get_delete_meetup_comment_view(self): def test_post_delete_meetup_comment_view(self): """Test POST request to delete a comment to a meetup""" self.client.login(username='foo', password='foobar') - url = reverse("delete_meetup_comment", kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'comment_pk': self.comment.id}) + url = reverse("delete_meetup_comment", kwargs={'meetup_slug': 'foo-bar-baz', + 'comment_pk': self.comment.id}) response = self.client.post(url) self.assertEqual(response.status_code, 302) @@ -1366,10 +611,10 @@ def test_post_delete_meetup_comment_view(self): self.assertEqual(len(comments), 1) -class RsvpMeetupViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class RsvpMeetupViewTestCase(MeetupBaseCase, TestCase): def test_get_rsvp_meetup_view(self): """Test GET request to rsvp a meetup""" - url = reverse('rsvp_meetup', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse('rsvp_meetup', kwargs={'meetup_slug': 'foo-bar-baz'}) response = self.client.get(url) self.assertEqual(response.status_code, 403) @@ -1392,7 +637,7 @@ def test_get_rsvp_meetup_view(self): def test_post_rsvp_meetup_view(self): """Test POST request to rsvp a meetup""" - url = reverse("rsvp_meetup", kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse("rsvp_meetup", kwargs={'meetup_slug': 'foo-bar-baz'}) response = self.client.post(url, data={}) self.assertEqual(response.status_code, 403) @@ -1406,7 +651,7 @@ def test_post_rsvp_meetup_view(self): self.assertTrue(rsvp[0].meetup, self.meetup) -class RsvpGoingViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class RsvpGoingViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(RsvpGoingViewTestCase, self).setUp() self.rsvp1 = Rsvp.objects.create(user=self.systers_user, meetup=self.meetup, @@ -1415,7 +660,7 @@ def setUp(self): def test_view_rsvp_going_view(self): """Test Rsvp going view for correct http response and all Rsvps in a list""" self.client.login(username='foo', password='foobar') - url = reverse("rsvp_going", kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse("rsvp_going", kwargs={'meetup_slug': 'foo-bar-baz'}) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "meetup/rsvp_going.html") @@ -1423,10 +668,10 @@ def test_view_rsvp_going_view(self): self.assertEqual(len(response.context['rsvp_list']), 1) -class AddSupportRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class AddSupportRequestViewTestCase(MeetupBaseCase, TestCase): def test_get_add_support_request_view(self): """Test GET request to add a new support request""" - url = reverse('add_support_request', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse('add_support_request', kwargs={'meetup_slug': 'foo-bar-baz'}) response = self.client.get(url) self.assertEqual(response.status_code, 403) @@ -1449,7 +694,7 @@ def test_get_add_support_request_view(self): def test_post_add_support_request_view(self): """Test POST request to add a new support request""" - url = reverse('add_support_request', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse('add_support_request', kwargs={'meetup_slug': 'foo-bar-baz'}) response = self.client.post(url, data={}) self.assertEqual(response.status_code, 403) @@ -1465,7 +710,7 @@ def test_post_add_support_request_view(self): self.assertTrue(support_requests[0].meetup, self.meetup) -class EditSupportRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class EditSupportRequestViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(EditSupportRequestViewTestCase, self).setUp() self.support_request = SupportRequest.objects.create( @@ -1474,8 +719,8 @@ def setUp(self): def test_get_edit_support_request_view(self): """Test GET request to edit a support request for a meetup""" - url = reverse('edit_support_request', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'pk': self.support_request.id}) + url = reverse('edit_support_request', kwargs={'meetup_slug': 'foo-bar-baz', + 'pk': self.support_request.id}) response = self.client.get(url) self.assertEqual(response.status_code, 403) @@ -1498,8 +743,8 @@ def test_get_edit_support_request_view(self): def test_post_edit_support_request_view(self): """Test POST request to edit a support request for a meetup""" - url = reverse('edit_support_request', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'pk': self.support_request.id}) + url = reverse('edit_support_request', kwargs={'meetup_slug': 'foo-bar-baz', + 'pk': self.support_request.id}) response = self.client.get(url, data={}) self.assertEqual(response.status_code, 403) @@ -1515,7 +760,7 @@ def test_post_edit_support_request_view(self): self.assertTrue(support_requests[0].meetup, self.meetup) -class DeleteSupportRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class DeleteSupportRequestViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(DeleteSupportRequestViewTestCase, self).setUp() self.support_request = SupportRequest.objects.create( @@ -1524,8 +769,8 @@ def setUp(self): def test_get_delete_support_request_view(self): """Test GET to confirm deletion of support request""" - url = reverse('delete_support_request', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'pk': self.support_request.id}) + url = reverse('delete_support_request', kwargs={'meetup_slug': 'foo-bar-baz', + 'pk': self.support_request.id}) response = self.client.get(url) self.assertEqual(response.status_code, 403) @@ -1536,8 +781,8 @@ def test_get_delete_support_request_view(self): def test_post_delete_support_request_view(self): """Test POST to delete support request""" - url = reverse('delete_support_request', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'pk': self.support_request.id}) + url = reverse('delete_support_request', kwargs={'meetup_slug': 'foo-bar-baz', + 'pk': self.support_request.id}) response = self.client.post(url) self.assertEqual(response.status_code, 403) @@ -1549,7 +794,7 @@ def test_post_delete_support_request_view(self): self.assertEqual(len(support_requests), 0) -class SupportRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class SupportRequestViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(SupportRequestViewTestCase, self).setUp() self.support_request = SupportRequest.objects.create( @@ -1558,8 +803,8 @@ def setUp(self): def test_view_support_request_view(self): """Test Support Request view for correct response""" - url = reverse('view_support_request', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz', - 'pk': self.support_request.id}) + url = reverse('view_support_request', kwargs={'meetup_slug': 'foo-bar-baz', + 'pk': self.support_request.id}) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'meetup/support_request.html') @@ -1567,7 +812,7 @@ def test_view_support_request_view(self): self.assertEqual(response.context['support_request'], self.support_request) -class SupportRequestsListViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class SupportRequestsListViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(SupportRequestsListViewTestCase, self).setUp() self.support_request1 = SupportRequest.objects.create( @@ -1580,7 +825,7 @@ def setUp(self): def test_view_support_requests_list_view(self): """Test Support Requests list view for correct http response and all support requests in a list""" - url = reverse('list_support_requests', kwargs={'slug': 'foo', 'meetup_slug': 'foo-bar-baz'}) + url = reverse('list_support_requests', kwargs={'meetup_slug': 'foo-bar-baz'}) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "meetup/list_support_requests.html") @@ -1589,7 +834,7 @@ def test_view_support_requests_list_view(self): "Support Request: 1") -class UnapprovedSupportRequestsListViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class UnapprovedSupportRequestsListViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(UnapprovedSupportRequestsListViewTestCase, self).setUp() self.support_request1 = SupportRequest.objects.create( @@ -1602,8 +847,7 @@ def setUp(self): def test_view_unapproved_support_requests_list_view(self): """Test unapproved Support Requests list view for correct http response and all support requests in a list""" - url = reverse('unapproved_support_requests', kwargs={'slug': 'foo', - 'meetup_slug': 'foo-bar-baz'}) + url = reverse('unapproved_support_requests', kwargs={'slug': 'foo-bar-baz'}) response = self.client.get(url) self.assertEqual(response.status_code, 302) @@ -1616,7 +860,7 @@ def test_view_unapproved_support_requests_list_view(self): "Support Request: 2") -class ApproveSupportRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class ApproveSupportRequestViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(ApproveSupportRequestViewTestCase, self).setUp() self.support_request1 = SupportRequest.objects.create( @@ -1628,24 +872,22 @@ def setUp(self): def test_view_approve_support_request_view(self): """Test approve support request view for correct http response""" - url = reverse('approve_support_request', kwargs={'slug': 'foo', - 'meetup_slug': 'foo-bar-baz', 'pk': self.support_request1.id}) + url = reverse('approve_support_request', + kwargs={'meetup_slug': 'foo-bar-baz', + 'pk': self.support_request1.id}) response = self.client.get(url) self.assertEqual(response.status_code, 403) self.client.login(username='foo', password='foobar') response = self.client.get(url, follow=True) self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/foo-bar-baz/unapproved_support_requests/') + self.assertRedirects(response, '/meetup/foo-bar-baz/unapproved_support_requests/') self.assertEqual(len(response.context['supportrequest_list']), 1) self.assertEqual(response.context['supportrequest_list'][0].description, "Support Request: 2") - self.assertEqual(len(mail.outbox), 1) - self.assertIn(self.user.email, mail.outbox[0].to) - self.assertIn('Support Request Approved', mail.outbox[0].subject) -class RejectSupportRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class RejectSupportRequestViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(RejectSupportRequestViewTestCase, self).setUp() self.support_request1 = SupportRequest.objects.create( @@ -1657,21 +899,22 @@ def setUp(self): def test_view_reject_support_request_view(self): """Test reject support request view for correct http response""" - url = reverse('reject_support_request', kwargs={'slug': 'foo', - 'meetup_slug': 'foo-bar-baz', 'pk': self.support_request1.id}) + url = reverse('reject_support_request', + kwargs={'meetup_slug': 'foo-bar-baz', + 'pk': self.support_request1.id}) response = self.client.get(url) self.assertEqual(response.status_code, 403) self.client.login(username='foo', password='foobar') response = self.client.get(url, follow=True) self.assertEqual(response.status_code, 200) - self.assertRedirects(response, '/meetup/foo/foo-bar-baz/unapproved_support_requests/') + self.assertRedirects(response, '/meetup/foo-bar-baz/unapproved_support_requests/') self.assertEqual(len(response.context['supportrequest_list']), 1) self.assertEqual(response.context['supportrequest_list'][0].description, "Support Request: 2") -class AddSupportRequestCommentViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class AddSupportRequestCommentViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(AddSupportRequestCommentViewTestCase, self).setUp() self.support_request = SupportRequest.objects.create( @@ -1680,8 +923,8 @@ def setUp(self): def test_get_add_support_request_comment_view(self): """Test GET request to add a comment to a support request""" - url = reverse('add_support_request_comment', kwargs={'slug': 'foo', - 'meetup_slug': 'foo-bar-baz', 'pk': self.support_request.pk}) + url = reverse('add_support_request_comment', kwargs={'meetup_slug': 'foo-bar-baz', + 'pk': self.support_request.pk}) response = self.client.get(url) self.assertEqual(response.status_code, 403) @@ -1704,8 +947,8 @@ def test_get_add_support_request_comment_view(self): def test_post_add_support_request_comment_view(self): """Test POST request to add a support request to a meetup""" - url = reverse('add_support_request_comment', kwargs={'slug': 'foo', - 'meetup_slug': 'foo-bar-baz', 'pk': self.support_request.pk}) + url = reverse('add_support_request_comment', kwargs={'meetup_slug': 'foo-bar-baz', + 'pk': self.support_request.pk}) response = self.client.get(url, data={}) self.assertEqual(response.status_code, 403) @@ -1721,7 +964,7 @@ def test_post_add_support_request_comment_view(self): self.assertEqual(comments[0].content_object, self.support_request) -class EditSupportRequestCommentViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class EditSupportRequestCommentViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(EditSupportRequestCommentViewTestCase, self).setUp() support_request_content_type = ContentType.objects.get(app_label='meetup', @@ -1736,8 +979,7 @@ def setUp(self): def test_get_edit_support_request_comment_view(self): """Test GET request to edit a comment to a support request""" - url = reverse('edit_support_request_comment', kwargs={'slug': 'foo', - 'meetup_slug': 'foo-bar-baz', + url = reverse('edit_support_request_comment', kwargs={'meetup_slug': 'foo-bar-baz', 'pk': self.support_request.pk, 'comment_pk': self.comment.pk}) response = self.client.get(url) @@ -1762,8 +1004,7 @@ def test_get_edit_support_request_comment_view(self): def test_post_edit_support_request_comment_view(self): """Test POST request to edit a comment to a support request""" - url = reverse('edit_support_request_comment', kwargs={'slug': 'foo', - 'meetup_slug': 'foo-bar-baz', + url = reverse('edit_support_request_comment', kwargs={'meetup_slug': 'foo-bar-baz', 'pk': self.support_request.pk, 'comment_pk': self.comment.pk}) response = self.client.get(url, data={}) @@ -1781,7 +1022,7 @@ def test_post_edit_support_request_comment_view(self): self.assertEqual(comments[0].content_object, self.support_request) -class DeleteSupportRequestCommentViewTestCase(MeetupLocationViewBaseTestCase, TestCase): +class DeleteSupportRequestCommentViewTestCase(MeetupBaseCase, TestCase): def setUp(self): super(DeleteSupportRequestCommentViewTestCase, self).setUp() support_request_content_type = ContentType.objects.get(app_label='meetup', @@ -1796,8 +1037,7 @@ def setUp(self): def test_get_delete_support_request_comment_view(self): """Test GET request to delete a comment to a support request""" - url = reverse('delete_support_request_comment', kwargs={'slug': 'foo', - 'meetup_slug': 'foo-bar-baz', + url = reverse('delete_support_request_comment', kwargs={'meetup_slug': 'foo-bar-baz', 'pk': self.support_request.pk, 'comment_pk': self.comment.pk}) response = self.client.get(url) @@ -1810,8 +1050,7 @@ def test_get_delete_support_request_comment_view(self): def test_post_delete_support_request_comment_view(self): """Test POST request to delete a comment to a support request""" - url = reverse('delete_support_request_comment', kwargs={'slug': 'foo', - 'meetup_slug': 'foo-bar-baz', + url = reverse('delete_support_request_comment', kwargs={'meetup_slug': 'foo-bar-baz', 'pk': self.support_request.pk, 'comment_pk': self.comment.pk}) response = self.client.get(url) @@ -1825,303 +1064,180 @@ def test_post_delete_support_request_comment_view(self): self.assertEqual(len(comments), 0) -class CancelMeetupLocationJoinRequestViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - super(CancelMeetupLocationJoinRequestViewTestCase, self).setUp() - self.password = 'foobar' - self.meetup_location.members.remove(self.systers_user) - - def test_cancel_meetup_location_join_request(self): - """Test GET request to cancel a join request to a meetup location""" - current_url = reverse("about_meetup_location", kwargs={'slug': 'foo'}) - self.data = { - 'current_url': current_url, - 'username': self.user.username - } - self.url = reverse("cancel_meetup_location_join_request", kwargs={ - 'slug': self.meetup_location.slug, - 'username': self.user.username - }) - response = self.client.get(self.url, {'current_url': current_url}) - self.assertEqual(response.status_code, 403) - - user = User.objects.create_user(username='bar', password=self.password) - self.client.login(username=user.username, password=self.password) - nonexistent_meetup_location_url = reverse("about_meetup_location", kwargs={'slug': 'new'}) - response = self.client.get(nonexistent_meetup_location_url, { - 'current_url': nonexistent_meetup_location_url, - 'username': self.user.username - }) - self.assertEqual(response.status_code, 404) - - self.check_message_in_response( - 'warning', - 'There is no pending request to join Foo Systers meetup location.', - 200 - ) - - self.meetup_location.join_requests.add(self.systers_user) - self.assertEqual(self.meetup_location.join_requests.all().count(), 1) - self.check_message_in_response( - 'success', - 'Your request to join Foo Systers meetup location was canceled.', - 200 - ) - self.assertEqual(self.meetup_location.join_requests.all().count(), 0) - - self.meetup_location.members.add(self.systers_user) - self.check_message_in_response( - 'warning', - 'You are already a member of Foo Systers meetup location. ' - 'There is no pending join request.', - 200 - ) - - def check_message_in_response(self, _message_tag=None, _message=None, status_code=None): - response = self.client.get(self.url, self.data, follow=True) - self.assertEqual(response.status_code, status_code) - for message in response.context['messages']: - self.assertEqual(message.tags, _message_tag) - self.assertTrue(_message in message.message) - +# class ApiForVmsViewTestCase(APITestCase, TestCase): +# def setUp(self): +# self.user = User.objects.create_user(username='foo', password='foobar', +# email='user@test.com') +# self.systers_user = SystersUser.objects.get(user=self.user) +# country = Country.objects.create(name='Bar', continent='AS') +# self.meetup_location = City.objects.create(name='Baz', display_name='Baz', +# country=country) +# # a meetup after the posted date +# self.meetup = Meetup.objects.create(title='Foo Bar Baz', slug='foo-bar-baz', +# date='2018-06-16', +# time=timezone.now().time(), +# description='This is test Meetup', +# venue='Foo Systers', +# meetup_location=self.meetup_location, +# created_by=self.systers_user, +# last_updated=timezone.now(), +# leader=self.systers_user, +# end_date='2018-12-16') +# # a meetup before the posted date +# self.meetup2 = Meetup.objects.create(title='Foo Baz', slug='foobar', +# date='2018-06-12', +# time=timezone.now().time(), +# description='This is new test Meetup', +# venue='Foo Systers', +# meetup_location=self.meetup_location, +# created_by=self.systers_user, +# leader=self.systers_user, +# last_updated=timezone.now(), +# end_date='2018-12-16') +# +# def test_api_for_vms_get(self): +# """Test GET request to provide data of all meetups""" +# url = reverse('vms_api') +# response = self.client.get(url) +# self.assertEqual(json.loads(response.content.decode('utf-8')), +# [{u'event_name': u'Foo Baz', +# u'venue': u'Foo Systers', +# u'start_date': u'2018-06-12', +# u'end_date': u'2018-12-16', +# u'meetup_id': 33, +# u'description': u'This is new test Meetup'}, +# {u'event_name': u'Foo Bar Baz', +# u'venue': u'Foo Systers', +# u'start_date': u'2018-06-16', +# u'end_date': u'2018-12-16', +# u'meetup_id': 32, +# u'description': u'This is test Meetup'}]) +# +# def test_api_for_vms_post(self): +# """Test POST request to provide data of meetups after the specified date""" +# url = reverse('vms_api') +# data = {'meetup_id': 38} +# response = self.client.post(url, data, format='json') +# self.assertEqual(json.loads(response.content.decode('utf-8')), +# [{u'event_name': u'Foo Baz', +# u'venue': u'Foo Systers', +# u'start_date': u'2018-06-12', +# u'end_date': u'2018-12-16', +# u'meetup_id': 41, +# u'description': u'This is new test Meetup'}, +# {u'event_name': u'Foo Bar Baz', +# u'venue': u'Foo Systers', +# u'start_date': u'2018-06-16', +# u'end_date': u'2018-12-16', +# u'meetup_id': 40, +# u'description': u'This is test Meetup'}]) + + +class UpcomingMeetupsSearchViewTestCase(MeetupBaseCase, TestCase): + maxDiff = None -class ApiForVmsViewTestCase(APITestCase, TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar', email='user@test.com') self.systers_user = SystersUser.objects.get(user=self.user) country = Country.objects.create(name='Bar', continent='AS') self.location = City.objects.create(name='Baz', display_name='Baz', country=country) - self.meetup_location = MeetupLocation.objects.create( - name="Foo Systers", slug="foo", location=self.location, - description="It's a test meetup location", sponsors="BarBaz", leader=self.systers_user) - # a meetup after the posted date self.meetup = Meetup.objects.create(title='Foo Bar Baz', slug='foo-bar-baz', - date='2018-06-16', + date=(timezone.now() + timezone.timedelta(4)).date(), time=timezone.now().time(), description='This is test Meetup', venue='Foo Systers', - meetup_location=self.meetup_location, - created_by=self.systers_user, - last_updated=timezone.now(), - end_date='2018-12-16') - # a meetup before the posted date - self.meetup2 = Meetup.objects.create(title='Foo Baz', slug='foobar', - date='2018-06-12', - time=timezone.now().time(), - description='This is new test Meetup', - venue='Foo Systers', - meetup_location=self.meetup_location, - created_by=self.systers_user, - last_updated=timezone.now(), - end_date='2018-12-16') - - def test_api_for_vms_get(self): - """Test GET request to provide data of all meetups""" - url = reverse('vms_api') - response = self.client.get(url) - self.assertEqual(json.loads(response.content.decode('utf-8')), - [{u'event_name': u'Foo Baz', - u'venue': u'Foo Systers', - u'start_date': u'2018-06-12', - u'end_date': u'2018-12-16', - u'meetup_id': 39, - u'description': u'This is new test Meetup'}, - {u'event_name': u'Foo Bar Baz', - u'venue': u'Foo Systers', - u'start_date': u'2018-06-16', - u'end_date': u'2018-12-16', - u'meetup_id': 38, - u'description': u'This is test Meetup'}]) - - def test_api_for_vms_post(self): - """Test POST request to provide data of meetups after the specified date""" - url = reverse('vms_api') - data = {'meetup_id': 38} - response = self.client.post(url, data, format='json') - self.assertEqual(json.loads(response.content.decode('utf-8')), - [{u'event_name': u'Foo Baz', - u'venue': u'Foo Systers', - u'start_date': u'2018-06-12', - u'end_date': u'2018-12-16', - u'meetup_id': 41, - u'description': u'This is new test Meetup'}, - {u'event_name': u'Foo Bar Baz', - u'venue': u'Foo Systers', - u'start_date': u'2018-06-16', - u'end_date': u'2018-12-16', - u'meetup_id': 40, - u'description': u'This is test Meetup'}]) - - -class UpcomingMeetupsSearchViewTestCase(MeetupLocationViewBaseTestCase, TestCase): - def setUp(self): - self.user = User.objects.create_user(username='foo', password='foobar', - email='user@test.com') - self.systers_user = SystersUser.objects.get(user=self.user) - country = Country.objects.create(name='Bar', continent='AS') - self.location = City.objects.create(name='Baz', display_name='Baz', country=country) - self.location1 = City.objects.all()[0] - self.meetup_location = MeetupLocation.objects.create( - name="Foo Systers", slug="foo", location=self.location, - description="It's a test meetup location", sponsors="BarBaz", leader=self.systers_user) - self.meetup_location1 = MeetupLocation.objects.create( - name="Foo Systers1", slug="foob", location=self.location1, - description="It's a meetup location", sponsors="BarBaz", leader=self.systers_user) - self.meetup = Meetup.objects.create(title='Foo Bar Baz', slug='foo-bar-baz', - date='2018-09-16', - time=timezone.now().time(), - description='This is test Meetup', - venue='Foo Systers', - meetup_location=self.meetup_location, + meetup_location=self.location, created_by=self.systers_user, + leader=self.systers_user, last_updated=timezone.now()) + self.meetup2 = Meetup.objects.create(title='Foo Baz', slug='foobar', - date='2018-06-12', + date=timezone.now().date(), time=timezone.now().time(), description='This is new test Meetup', venue='Foo Systers', - meetup_location=self.meetup_location, + meetup_location=self.location, created_by=self.systers_user, + leader=self.systers_user, last_updated=timezone.now()) + self.meetup3 = Meetup.objects.create(title='Foob Baz', slug='foobarbaz', - date='2018-06-13', + date=(timezone.now() + timezone.timedelta(2)).date(), time=timezone.now().time(), description='This is test Meetup', venue='Foo Systers', - meetup_location=self.meetup_location1, + meetup_location=self.location, + leader=self.systers_user, created_by=self.systers_user, last_updated=timezone.now()) def test_post_view(self): """Test post view for all search requests""" url = reverse('search_meetups') - data = {'date': '2018-06-12', 'meeetup_location': 'Foo Systers', 'keyword': 'new'} + data = {'keyword': 'Foo Baz'} response = self.client.post(url, data, format='json') self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-12', - 'meetup': 'Foo Baz', - 'location': 'Foo Systers', - 'location_slug': 'foo', - 'meetup_slug': 'foobar', - 'distance': '', - 'unit': ''}]}) - - data1 = {'date': '2018-06-13', 'meeetup_location': 'Foo Systers1', 'keyword': 'test', - 'filter': 'distance'} + {'search_results': [{'date': self.meetup2.date.isoformat(), + 'meetup': 'Foo Baz', + 'location': 'Baz', + 'meetup_slug': 'foobar', + 'distance': 900}], + 'unit': 'kilometers from your location'}) + + data1 = {'keyword': 'Foo Bar'} response = self.client.post(url, data1, format='json') self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-13', - 'meetup': 'Foob Baz', - 'location': 'Foo Systers1', - 'location_slug': 'foob', - 'meetup_slug': 'foobarbaz', - 'distance': 900, - 'unit': 'kilometers from your location'}]}) - - data2 = {'date': '2018-06-12', 'meeetup_location': 'Meetup Location'} + {'search_results': [{'date': self.meetup.date.isoformat(), + 'meetup': 'Foo Bar Baz', + 'location': 'Baz', + 'meetup_slug': 'foo-bar-baz', + 'distance': 900}], + 'unit': 'kilometers from your location'}) + + data2 = {'keyword': 'Foo Bar', 'location': 'Baz'} response = self.client.post(url, data2, format='json') self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-12', - 'meetup': 'Foo Baz', - 'location': 'Foo Systers', - 'location_slug': 'foo', - 'meetup_slug': 'foobar', - 'distance': '', - 'unit': ''}]}) + {'search_results': [{'date': self.meetup.date.isoformat(), + 'meetup': 'Foo Bar Baz', + 'location': 'Baz', + 'meetup_slug': 'foo-bar-baz', + 'distance': 0}], + 'unit': 'kilometers from your location'}) data3 = {'keyword': 'new'} response = self.client.post(url, data3, format='json') self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-12', - 'meetup': 'Foo Baz', - 'location': 'Foo Systers', - 'location_slug': 'foo', - 'meetup_slug': 'foobar', - 'distance': '', - 'unit': ''}]}) - - data4 = {'meetup_location': 'Foo Systers1'} + {'search_results': [], + 'unit': ''}) + + data4 = {'keyword': 'Foob'} response = self.client.post(url, data4, format='json') self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-13', - 'meetup': 'Foob Baz', - 'location': 'Foo Systers1', - 'location_slug': 'foob', - 'meetup_slug': 'foobarbaz', - 'distance': '', - 'unit': ''}]}) - - data5 = {'meetup_location': 'Foo Systers1', 'date': '2018-06-13'} + {'search_results': [{'date': self.meetup3.date.isoformat(), + 'meetup': 'Foob Baz', + 'location': 'Baz', + 'meetup_slug': 'foobarbaz', + 'distance': 900}], + 'unit': 'kilometers from your location'}) + + data5 = {'keyword': 'Foo', 'location': 'Baz'} response = self.client.post(url, data5, format='json') self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-13', - 'meetup': 'Foob Baz', - 'location': 'Foo Systers1', - 'location_slug': 'foob', - 'meetup_slug': 'foobarbaz', - 'distance': '', - 'unit': ''}]}) - - data6 = {'keyword': 'new', 'date': '2018-06-12'} - response = self.client.post(url, data6, format='json') - self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-12', - 'meetup': 'Foo Baz', - 'location': 'Foo Systers', - 'location_slug': 'foo', - 'meetup_slug': 'foobar', - 'distance': '', - 'unit': ''}]}) - - data7 = {'keyword': 'new', 'meetup_location': 'Foo Systers'} - response = self.client.post(url, data7, format='json') - self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-12', - 'meetup': 'Foo Baz', - 'location': 'Foo Systers', - 'location_slug': 'foo', - 'meetup_slug': 'foobar', - 'distance': '', - 'unit': ''}]}) - data8 = {'date': '2018-06-12'} - response = self.client.post(url, data8, format='json') - self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-12', - 'meetup': 'Foo Baz', - 'location': 'Foo Systers', - 'location_slug': 'foo', - 'meetup_slug': 'foobar', - 'distance': '', - 'unit': ''}]}) - data9 = {'date': '2018-06-13'} - response = self.client.post(url, data9, format='json') - self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-13', - 'meetup': 'Foob Baz', - 'location': 'Foo Systers1', - 'location_slug': 'foob', - 'meetup_slug': 'foobarbaz', - 'distance': '', - 'unit': ''}]}) - data10 = {'keyword': 'test', 'date': '2018-06-13'} - response = self.client.post(url, data10, format='json') - self.assertEqual(json.loads(response.content.decode('utf-8')), - {'search_results': - [{'date': '2018-06-13', - 'meetup': 'Foob Baz', - 'location': 'Foo Systers1', - 'location_slug': 'foob', - 'meetup_slug': 'foobarbaz', - 'distance': '', - 'unit': ''}]}) + {'search_results': [{'date': self.meetup2.date.isoformat(), + 'meetup': 'Foo Baz', + 'location': 'Baz', + 'meetup_slug': 'foobar', + 'distance': 0}, + {'date': self.meetup3.date.isoformat(), + 'meetup': 'Foob Baz', + 'location': 'Baz', + 'meetup_slug': 'foobarbaz', + 'distance': 0}, + {'date': self.meetup.date.isoformat(), + 'meetup': 'Foo Bar Baz', + 'location': 'Baz', + 'meetup_slug': 'foo-bar-baz', + 'distance': 0}, + ], + 'unit': 'kilometers from your location'}) diff --git a/systers_portal/meetup/urls.py b/systers_portal/meetup/urls.py index eda9a12c..8e065a86 100644 --- a/systers_portal/meetup/urls.py +++ b/systers_portal/meetup/urls.py @@ -1,144 +1,89 @@ from django.conf.urls import url -from meetup.views import (MeetupLocationAboutView, MeetupLocationList, MeetupView, - MeetupLocationMembersView, AddMeetupView, DeleteMeetupView, - EditMeetupView, UpcomingMeetupsView, PastMeetupListView, - MeetupLocationSponsorsView, RemoveMeetupLocationMemberView, - AddMeetupLocationMemberView, RemoveMeetupLocationModeratorView, - MakeMeetupLocationModeratorView, ApproveMeetupLocationJoinRequestView, - RejectMeetupLocationJoinRequestView, MeetupLocationJoinRequestsView, - AddMeetupLocationView, EditMeetupLocationView, DeleteMeetupLocationView, - JoinMeetupLocationView, AddMeetupCommentView, EditMeetupCommentView, - DeleteMeetupCommentView, RsvpMeetupView, RsvpGoingView, - AddSupportRequestView, EditSupportRequestView, DeleteSupportRequestView, - SupportRequestView, SupportRequestsListView, ApproveSupportRequestView, - RejectSupportRequestView, UnapprovedSupportRequestsListView, - AddSupportRequestCommentView, EditSupportRequestCommentView, - DeleteSupportRequestCommentView, RequestMeetupLocationView, - NewMeetupLocationRequestsListView, ViewMeetupLocationRequestView, - RejectMeetupLocationRequestView, ApproveRequestMeetupLocationView, - RequestMeetupView, NewMeetupRequestsListView, ViewMeetupRequestView, - ApproveRequestMeetupView, RejectMeetupRequestView, - CancelMeetupLocationJoinRequestView, ApiForVmsView, - AllUpcomingMeetupsView, UpcomingMeetupsSearchView) - +from .views import (MeetupView, AddMeetupView, DeleteMeetupView, + EditMeetupView, UpcomingMeetupsView, PastMeetupListView, + AddMeetupCommentView, EditMeetupCommentView, + DeleteMeetupCommentView, RsvpMeetupView, RsvpGoingView, + AddSupportRequestView, EditSupportRequestView, DeleteSupportRequestView, + SupportRequestView, SupportRequestsListView, ApproveSupportRequestView, + RejectSupportRequestView, UnapprovedSupportRequestsListView, + RequestMeetupView, NewMeetupRequestsListView, ViewMeetupRequestView, + ApproveRequestMeetupView, RejectMeetupRequestView, ApiForVmsView, + AllUpcomingMeetupsView, AddSupportRequestCommentView, + EditSupportRequestCommentView, DeleteSupportRequestCommentView, + UpcomingMeetupsSearchView) urlpatterns = [ - url(r'^(?P[\w-]+)/about/$', MeetupLocationAboutView.as_view(), - name='about_meetup_location'), - url(r'^(?P[\w-]+)/upcoming/$', UpcomingMeetupsView.as_view(), + url(r'^upcoming/$', UpcomingMeetupsView.as_view(), name='upcoming_meetups'), - url(r'^(?P[\w-]+)/past/$', PastMeetupListView.as_view(), + url(r'^past/$', PastMeetupListView.as_view(), name='past_meetups'), - url(r'^(?P[\w-]+)/members/$', MeetupLocationMembersView.as_view(), - name='members_meetup_location'), - url(r'^(?P[\w-]+)/add/$', AddMeetupView.as_view(), name='add_meetup'), - url(r'^(?P[\w-]+)/(?P[\w-]+)/delete/$', DeleteMeetupView.as_view(), + url(r'^add/$', AddMeetupView.as_view(), name='add_meetup'), + url(r'^(?P[\w-]+)/delete/$', DeleteMeetupView.as_view(), name='delete_meetup'), - url(r'^(?P[\w-]+)/(?P[\w-]+)/edit/$', EditMeetupView.as_view(), + url(r'^(?P[\w-]+)/edit/$', EditMeetupView.as_view(), name="edit_meetup"), - url(r'^(?P[\w-]+)/approve-location-request/$', ApproveRequestMeetupLocationView.as_view(), - name='approve_meetup_location_request'), - url(r'^(?P[\w-]+)/view-request/$', ViewMeetupLocationRequestView.as_view(), - name='view_meetup_location_request'), - url(r'view-requests/$', NewMeetupLocationRequestsListView.as_view(), - name='new_meetup_location_requests'), - url(r'^(?P[\w-]+)/reject-request/$', RejectMeetupLocationRequestView.as_view(), - name='reject_meetup_location_request'), - url(r'^(?P[\w-]+)/request/$', RequestMeetupView.as_view(), + url(r'^request/$', RequestMeetupView.as_view(), name="request_meetup"), - url(r'^(?P[\w-]+)/view_meetup_requests/$', NewMeetupRequestsListView.as_view(), + url(r'^view_meetup_requests/$', NewMeetupRequestsListView.as_view(), name="new_meetup_requests"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/view_meetup_requests/$', + url(r'^(?P[\w-]+)/view_meetup_requests/$', ViewMeetupRequestView.as_view(), name="view_meetup_request"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/approve_meetup_request/$', + url(r'^(?P[\w-]+)/approve_meetup_request/$', ApproveRequestMeetupView.as_view(), name="approve_meetup_request"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/reject_meetup_request/$', + url(r'^(?P[\w-]+)/reject_meetup_request/$', RejectMeetupRequestView.as_view(), name="reject_meetup_request"), - url(r'locations/$', MeetupLocationList.as_view(), name='list_meetup_location'), - url(r'all-upcoming-meetups/search/$', UpcomingMeetupsSearchView.as_view(), + url(r'^all/search/$', UpcomingMeetupsSearchView.as_view(), name='search_meetups'), - url(r'all-upcoming-meetups/$', AllUpcomingMeetupsView.as_view(), + url(r'^all/$', AllUpcomingMeetupsView.as_view(), name='all_upcoming_meetups'), - url(r'^(?P[\w-]+)/sponsors/$', MeetupLocationSponsorsView.as_view(), - name='sponsors_meetup_location'), - url(r'^(?P[\w-]+)/remove/(?P[\w.@+-]+)/$', - RemoveMeetupLocationMemberView.as_view(), - name='remove_member_meetup_location'), - url(r'^(?P[\w-]+)/add_member/$', AddMeetupLocationMemberView.as_view(), - name='add_member_meetup_location'), - url(r'^(?P[\w-]+)/remove_moderator/(?P[\w.@+-]+)/$', - RemoveMeetupLocationModeratorView.as_view(), - name='remove_moderator_meetup_location'), - url(r'^(?P[\w-]+)/make_moderator/(?P[\w.@+-]+)/$', - MakeMeetupLocationModeratorView.as_view(), - name='make_moderator_meetup_location'), - url(r'^(?P[\w-]+)/join/(?P[\w.@+-]+)/$', JoinMeetupLocationView.as_view(), - name='join_meetup_location'), - url(r'^(?P[\w-]+)/cancel/(?P[\w.@+-]+)/$', - CancelMeetupLocationJoinRequestView.as_view(), - name='cancel_meetup_location_join_request'), - url(r'^(?P[\w-]+)/join_requests/$', MeetupLocationJoinRequestsView.as_view(), - name='join_requests_meetup_location'), - url(r'^(?P[\w-]+)/join_requests/approve/(?P[\w.@+-]+)/$', - ApproveMeetupLocationJoinRequestView.as_view(), - name='approve_join_request_meetup_location'), - url(r'^(?P[\w-]+)/join_requests/reject/(?P[\w.@+-]+)/$', - RejectMeetupLocationJoinRequestView.as_view(), - name='reject_join_request_meetup_location'), - url(r'add/$', AddMeetupLocationView.as_view(), name="add_meetup_location"), - url(r'request-meetuplocation/$', RequestMeetupLocationView.as_view(), - name="request_meetup_location"), - url(r'^(?P[\w-]+)/edit/$', EditMeetupLocationView.as_view(), name="edit_meetup_location"), - url(r'^(?P[\w-]+)/delete/$', DeleteMeetupLocationView.as_view(), - name='delete_meetup_location'), - url(r'^(?P[\w-]+)/(?P[\w-]+)/add_comment/$', AddMeetupCommentView.as_view(), + url(r'^(?P[\w-]+)/add_comment/$', AddMeetupCommentView.as_view(), name="add_meetup_comment"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/edit_comment/(?P\d+)/$', + url(r'^(?P[\w-]+)/edit_comment/(?P\d+)/$', EditMeetupCommentView.as_view(), name="edit_meetup_comment"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/delete_comment/(?P\d+)/$', + url(r'^(?P[\w-]+)/delete_comment/(?P\d+)/$', DeleteMeetupCommentView.as_view(), name="delete_meetup_comment"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/rsvp/$', RsvpMeetupView.as_view(), + url(r'^(?P[\w-]+)/rsvp/$', RsvpMeetupView.as_view(), name="rsvp_meetup"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/going/$', RsvpGoingView.as_view(), + url(r'^(?P[\w-]+)/going/$', RsvpGoingView.as_view(), name="rsvp_going"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/add_support_request/$', + url(r'^(?P[\w-]+)/add_support_request/$', AddSupportRequestView.as_view(), name='add_support_request'), - url(r'^(?P[\w-]+)/(?P[\w-]+)/edit_support_request/(?P\d+)/$', + url(r'^(?P[\w-]+)/edit_support_request/(?P\d+)/$', EditSupportRequestView.as_view(), name="edit_support_request"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/delete_support_request/(?P\d+)/$', + url(r'^(?P[\w-]+)/delete_support_request/(?P\d+)/$', DeleteSupportRequestView.as_view(), name='delete_support_request'), - url(r'^(?P[\w-]+)/(?P[\w-]+)/support_request/(?P\d+)/$', + url(r'^(?P[\w-]+)/support_request/(?P\d+)/$', SupportRequestView.as_view(), name="view_support_request"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/support_requests_list/$', + url(r'^(?P[\w-]+)/support_requests_list/$', SupportRequestsListView.as_view(), name="list_support_requests"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/unapproved_support_requests/$', + url(r'^(?P[\w-]+)/unapproved_support_requests/$', UnapprovedSupportRequestsListView.as_view(), name="unapproved_support_requests"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/support_request/approve/(?P\d+)/$', + url(r'^(?P[\w-]+)/support_request/approve/(?P\d+)/$', ApproveSupportRequestView.as_view(), name='approve_support_request'), - url(r'^(?P[\w-]+)/(?P[\w-]+)/support_request/reject/(?P\d+)/$', + url(r'^(?P[\w-]+)/support_request/reject/(?P\d+)/$', RejectSupportRequestView.as_view(), name='reject_support_request'), - url(r'^(?P[\w-]+)/(?P[\w-]+)/support_request/(?P\d+)/add_comment/$', + url(r'^(?P[\w-]+)/support_request/(?P\d+)/add_comment/$', AddSupportRequestCommentView.as_view(), name="add_support_request_comment"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/support_request/(?P\d+)/edit_comment/' - '(?P\d+)/$', + url(r'^(?P[\w-]+)/support_request/(?P\d+)/edit_comment/' + r'(?P\d+)/$', EditSupportRequestCommentView.as_view(), name="edit_support_request_comment"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/support_request/(?P\d+)/delete_comment/' - '(?P\d+)/$', + url(r'^(?P[\w-]+)/support_request/(?P\d+)/delete_comment/' + r'(?P\d+)/$', DeleteSupportRequestCommentView.as_view(), name="delete_support_request_comment"), - url(r'^(?P[\w-]+)/(?P[\w-]+)/$', MeetupView.as_view(), name="view_meetup"), + url(r'^(?P[\w-]+)/$', MeetupView.as_view(), name="view_meetup"), url(r'^api/v1/request_meetup_data/$', ApiForVmsView.as_view(), name='vms_api'), ] diff --git a/systers_portal/meetup/utils.py b/systers_portal/meetup/utils.py index 56771d1e..98279ce6 100644 --- a/systers_portal/meetup/utils.py +++ b/systers_portal/meetup/utils.py @@ -1,58 +1,50 @@ from django.contrib.auth.models import Group, Permission from django.db import transaction -from guardian.shortcuts import assign_perm from meetup.permissions import groups_templates, group_permissions @transaction.atomic -def create_groups(meetup_location): +def create_groups(meetup): """Create groups for a Meetup Location instance using its name + :param meetup: :param meetup_location: string name of meetup location :return: list of meetup location Group objects """ - meetup_location_groups = [] + meetup_groups = [] for key, group_name in groups_templates.items(): group, created = Group.objects.get_or_create( - name=group_name.format(meetup_location)) - meetup_location_groups.append(group) - return meetup_location_groups + name=group_name.format(meetup)) + meetup_groups.append(group) + return meetup_groups @transaction.atomic -def remove_groups(meetup_location): +def remove_groups(meetup): """Remove groups for a particular Meetup Location instance using its name - - :param meetup_location: string name of meetup location """ - name = "{0}:".format(meetup_location) + name = "{0}:".format(meetup) Group.objects.filter(name__startswith=name).delete() -def get_groups(meetup_location): +def get_groups(meetup): """Get groups of a particular Meetup Location instance using its name - :param meetup_location: string name of Meetup Location + :param meetup: :return: list of Group objects """ - name = "{0}:".format(meetup_location) + name = "{0}:".format(meetup) return Group.objects.filter(name__startswith=name) -def assign_permissions(meetup_location, groups): +def assign_permissions(meetup, groups): """Assign row-level permissions to meetup location groups and meetup location object - - :param meetup_location: Meetup Location object :param groups: list of Group objects """ for key, group_name in groups_templates.items(): group = next( - g for g in groups if g.name == group_name.format(meetup_location.name)) + g for g in groups if g.name == group_name.format(meetup.title)) for perm in group_permissions[key]: - if (perm.endswith('meetup') or perm.endswith('meetuplocation') or - perm.endswith('supportrequest')): - group.permissions.add(Permission.objects.get(codename=perm)) - group.save() - else: - assign_perm(perm, group, meetup_location) + group.permissions.add(Permission.objects.filter(codename=perm).first()) + group.save() diff --git a/systers_portal/meetup/views.py b/systers_portal/meetup/views.py index 72bb4f0d..eae68d9d 100644 --- a/systers_portal/meetup/views.py +++ b/systers_portal/meetup/views.py @@ -1,43 +1,40 @@ import datetime import operator -from django.core.urlresolvers import reverse +from django.contrib.gis.geoip2 import GeoIP2 +from django.contrib.gis.geos import Point +from django.urls import reverse +from django.db.models import Q from django.shortcuts import get_object_or_404 -from django.views.generic import DeleteView, TemplateView, RedirectView -from django.views.generic.detail import DetailView, SingleObjectMixin +from django.views.decorators.csrf import csrf_exempt +from django.views.generic import DeleteView, RedirectView +from django.views.generic.detail import DetailView from django.views.generic.edit import CreateView, UpdateView, FormView from django.views.generic.list import ListView -from braces.views import LoginRequiredMixin, PermissionRequiredMixin, StaffuserRequiredMixin -from django.contrib.auth.models import User +from braces.views import LoginRequiredMixin, PermissionRequiredMixin from django.contrib import messages from django.contrib.contenttypes.models import ContentType from django.http import JsonResponse -from pinax.notifications import models as notification from braces.views import FormValidMessageMixin, FormInvalidMessageMixin -from meetup.forms import (AddMeetupForm, EditMeetupForm, AddMeetupLocationMemberForm, - AddMeetupLocationForm, EditMeetupLocationForm, AddMeetupCommentForm, - EditMeetupCommentForm, RsvpForm, AddSupportRequestForm, - EditSupportRequestForm, AddSupportRequestCommentForm, - EditSupportRequestCommentForm, RequestMeetupLocationForm, - RequestMeetupForm) -from meetup.mixins import MeetupLocationMixin -from meetup.models import (Meetup, MeetupLocation, Rsvp, SupportRequest, RequestMeetupLocation, - RequestMeetup) -from meetup.constants import (OK, SUCCESS_MSG, NAME_ALREADY_EXISTS, NAME_ALREADY_EXISTS_MSG, - SLUG_ALREADY_EXISTS, SLUG_ALREADY_EXISTS_MSG, - LOCATION_ALREADY_EXISTS, LOCATION_ALREADY_EXISTS_MSG, ERROR_MSG, - SUCCESS_MEETUP_MSG) +from geopy import Nominatim +from ipware import get_client_ip + +from .forms import (AddMeetupForm, EditMeetupForm, AddMeetupCommentForm, + EditMeetupCommentForm, RsvpForm, AddSupportRequestForm, + EditSupportRequestForm, AddSupportRequestCommentForm, + EditSupportRequestCommentForm, + RequestMeetupForm) +from .models import (Meetup, Rsvp, SupportRequest, + RequestMeetup) +from .constants import (OK, SLUG_ALREADY_EXISTS, SLUG_ALREADY_EXISTS_MSG, + ERROR_MSG, SUCCESS_MEETUP_MSG) from users.models import SystersUser from common.models import Comment from rest_framework.views import APIView -from django.views.decorators.csrf import csrf_exempt from cities_light.models import City -from geopy.geocoders import Nominatim -from django.contrib.gis.geos import Point -from django.db.models import Q -class RequestMeetupView(LoginRequiredMixin, MeetupLocationMixin, CreateView): +class RequestMeetupView(LoginRequiredMixin, CreateView): """View to Request a new meetup""" template_name = "meetup/request_new_meetup.html" model = RequestMeetup @@ -46,29 +43,21 @@ class RequestMeetupView(LoginRequiredMixin, MeetupLocationMixin, CreateView): def get_success_url(self): """Supply the redirect URL in case of successful submit""" - message = "Your request for a new meetup is successfully submitted. "\ + message = "Your request for a new meetup is successfully submitted. " \ "Please wait until someone reviews your request. " messages.add_message(self.request, messages.SUCCESS, message) - return reverse('about_meetup_location', kwargs={'slug': self.meetup_location.slug}) + return reverse('upcoming_meetups') def get_form_kwargs(self): - """Add request user, meetup location to the form kwargs. + """Add request user to the form kwargs. Used to autofill form fields with requestor without explicitly filling them up in the form.""" kwargs = super(RequestMeetupView, self).get_form_kwargs() - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - kwargs.update({'meetup_location': self.meetup_location}) kwargs.update({'created_by': self.request.user}) return kwargs - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.meetup_location - -class NewMeetupRequestsListView(LoginRequiredMixin, PermissionRequiredMixin, MeetupLocationMixin, - ListView): +class NewMeetupRequestsListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): """List of New Meetup Requests""" template_name = "meetup/new_meetup_requests.html" model = RequestMeetup @@ -77,24 +66,17 @@ class NewMeetupRequestsListView(LoginRequiredMixin, PermissionRequiredMixin, Mee def get_queryset(self, **kwargs): """Set ListView queryset to all the unapproved meetup requests""" - request_meetups_list = RequestMeetup.objects.filter( - meetup_location=self.meetup_location, is_approved=False).order_by('date', 'time') + request_meetups_list = \ + RequestMeetup.objects.filter(is_approved=False).order_by('date', 'time') return request_meetups_list - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - def check_permissions(self, request): """Check if the request user has the permission to view the meetup requests. The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.request.user.has_perm("view_meetup_location_meetuprequest", - self.meetup_location) + return self.request.user.has_perm('meetup.view_meetup_request') -class ViewMeetupRequestView(LoginRequiredMixin, PermissionRequiredMixin, MeetupLocationMixin, - FormView): +class ViewMeetupRequestView(LoginRequiredMixin, PermissionRequiredMixin, FormView): """View the meetup request""" template_name = "meetup/view_new_meetup_request.html" form_class = RequestMeetupForm @@ -104,11 +86,9 @@ def get_context_data(self, **kwargs): """Add RequestMeetup object and it's verbose fields to the context.""" context = super(ViewMeetupRequestView, self).get_context_data(**kwargs) - self.meetup_request = get_object_or_404( - RequestMeetup, meetup_location=self.meetup_location, slug=self.kwargs['meetup_slug']) + self.meetup_request = get_object_or_404(RequestMeetup, slug=self.kwargs['meetup_slug']) context['meetup_request'] = self.meetup_request - context['meetup_request_fields'] = \ - self.meetup_request.get_verbose_fields() + context['meetup_request_fields'] = self.meetup_request.get_verbose_fields() return context def get_form_kwargs(self): @@ -116,20 +96,16 @@ def get_form_kwargs(self): Used to autofill form fields with requestor without explicitly filling them up in the form.""" kwargs = super(ViewMeetupRequestView, self).get_form_kwargs() - kwargs.update({'meetup_location': self.meetup_location}) kwargs.update({'created_by': self.request.user}) return kwargs def check_permissions(self, request): - """Check if the request user has the permission to view meetup request in meetup location. + """Check if the request user has the permission to view meetup request . The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.request.user.has_perm("view_meetup_location_meetuprequest", - self.meetup_location) + return self.request.user.has_perm("meetup.view_meetup_request") -class ApproveRequestMeetupView(LoginRequiredMixin, PermissionRequiredMixin, MeetupLocationMixin, - RedirectView): +class ApproveRequestMeetupView(LoginRequiredMixin, PermissionRequiredMixin, RedirectView): """Approve the new meetup request""" model = RequestMeetup permanent = False @@ -139,11 +115,9 @@ def get_redirect_url(self, *args, **kwargs): """Supply the redirect URL in case of successful approval. * Creates a new RequestMeetup object and copy fields, values from RequestMeetup object - * Adds the requestor as the meetup location moderator * Sets the RequestMeetup object's is_approved field to True. """ - meetup_request = get_object_or_404( - RequestMeetup, slug=self.kwargs['meetup_slug'], meetup_location=self.meetup_location) + meetup_request = get_object_or_404(RequestMeetup, slug=self.kwargs['meetup_slug']) new_meetup = Meetup() new_meetup.title = meetup_request.title new_meetup.slug = meetup_request.slug @@ -152,24 +126,19 @@ def get_redirect_url(self, *args, **kwargs): new_meetup.venue = meetup_request.venue new_meetup.description = meetup_request.description new_meetup.meetup_location = meetup_request.meetup_location - systersuser = meetup_request.created_by - + new_meetup.leader = meetup_request.created_by + meetup_request.is_approved = True meetup_request.approved_by = get_object_or_404( SystersUser, user=self.request.user) - meetup_request.is_approved = True + meetup_request.save() self.slug_meetup_request = meetup_request.slug status, message, level = self.process_request() messages.add_message(self.request, level, message) - moderators = self.meetup_location.moderators.all() if status == OK: new_meetup.save() - if systersuser not in moderators: - self.meetup_location.moderators.add(systersuser) - meetup_request.save() - return reverse('view_meetup', kwargs={'slug': self.meetup_location.slug, - 'meetup_slug': new_meetup.slug}) + return reverse('view_meetup', kwargs={'slug': new_meetup.slug}) else: - return reverse('new_meetup_requests', kwargs={'slug': self.meetup_location.slug}) + return reverse('new_meetup_requests') def process_request(self): """If an error occurs during the creation of a new meetup, this method returns the @@ -178,18 +147,16 @@ def process_request(self): ).values_list('slug', flat=True) if self.slug_meetup_request in self.slug_meetup_values: STATUS = SLUG_ALREADY_EXISTS - return STATUS, SLUG_ALREADY_EXISTS_MSG.format(self.slug_meetup_request),\ - messages.WARNING + return \ + STATUS, SLUG_ALREADY_EXISTS_MSG.format(self.slug_meetup_request), messages.WARNING else: STATUS = OK return STATUS, SUCCESS_MEETUP_MSG, messages.INFO def check_permissions(self, request): - """Check if the request user has the permission to add a meetup to the meetup location. + """Check if the request user has the permission to add a meetup . The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.request.user.has_perm("approve_meetup_location_meetuprequest", - self.meetup_location) + return self.request.user.has_perm("meetup.approve_meetup_request") class RejectMeetupRequestView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView): @@ -202,180 +169,19 @@ def get_success_url(self, *args, **kwargs): """Supply the success URL in case of a successful submit""" messages.add_message(self.request, messages.INFO, "Meetup request successfullly rejected!") - self.meetup_request = get_object_or_404(RequestMeetup, slug=self.kwargs['meetup_slug'], - meetup_location=self.meetup_location) + self.meetup_request = get_object_or_404(RequestMeetup, slug=self.kwargs['meetup_slug']) self.meetup_request.delete() - return reverse('new_meetup_requests', kwargs={'slug': self.kwargs['slug']}) + return reverse('new_meetup_requests') def get_object(self, queryset=None): """Returns the RequestMeetup object""" - self.meetup_request = get_object_or_404(RequestMeetup, slug=self.kwargs['meetup_slug'], - meetup_location=self.meetup_location) + self.meetup_request = get_object_or_404(RequestMeetup, slug=self.kwargs['meetup_slug']) return self.meetup_request def check_permissions(self, request): - """Check if the request user has the permission to reject a meetup in the meetup location. + """Check if the request user has the permission to reject a meetup. The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.request.user.has_perm("reject_meetup_location_meetuprequest", - self.meetup_location) - - -class RequestMeetupLocationView(LoginRequiredMixin, CreateView): - """View to Request a new meetup location""" - template_name = "meetup/request_new_meetup_location.html" - model = RequestMeetupLocation - form_class = RequestMeetupLocationForm - raise_exception = True - - def get_success_url(self): - """Supply the redirect URL in case of successful submit""" - message = "Your request for a new meetup location is successfully submitted. "\ - "Please wait until someone reviews your request. " - messages.add_message(self.request, messages.SUCCESS, message) - return reverse("list_meetup_location") - - def get_form_kwargs(self): - """Add request user to the form kwargs. - Used to autofill form fields with requestor without - explicitly filling them up in the form.""" - kwargs = super(RequestMeetupLocationView, self).get_form_kwargs() - kwargs.update({'user': self.request.user}) - return kwargs - - -class NewMeetupLocationRequestsListView(LoginRequiredMixin, StaffuserRequiredMixin, ListView): - """List of Meetup Location Requests""" - template_name = "meetup/new_meetup_location_requests.html" - model = RequestMeetupLocation - raise_exception = True - paginate_by = 10 - - def get_queryset(self, **kwargs): - """Set ListView queryset to all the unapproved meetup location requests""" - request_meetup_location_list = RequestMeetupLocation.objects.filter( - is_approved=False) - return request_meetup_location_list - - -class ViewMeetupLocationRequestView(LoginRequiredMixin, StaffuserRequiredMixin, - FormView): - """View the meetup location request""" - template_name = "meetup/view_new_meetup_location_request.html" - form_class = RequestMeetupLocationForm - raise_exception = True - - def get_context_data(self, **kwargs): - """Add RequestMeetupLocation object and it's verbose fields to the context.""" - context = super(ViewMeetupLocationRequestView, - self).get_context_data(**kwargs) - self.meetup_location_request = get_object_or_404( - RequestMeetupLocation, slug=self.kwargs['slug']) - context['meetup_location_request'] = self.meetup_location_request - context['meetup_location_request_fields'] = \ - self.meetup_location_request.get_verbose_fields() - return context - - def get_form_kwargs(self): - """Add request user to the form kwargs. - Used to autofill form fields with requestor without - explicitly filling them up in the form.""" - kwargs = super(ViewMeetupLocationRequestView, self).get_form_kwargs() - kwargs.update({'user': self.request.user}) - return kwargs - - -class ApproveRequestMeetupLocationView(LoginRequiredMixin, StaffuserRequiredMixin, - RedirectView): - """Approve the new meetup location request""" - model = RequestMeetupLocation - permanent = False - raise_exception = True - - def get_redirect_url(self, *args, **kwargs): - """Supply the redirect URL in case of successful approval. - * Creates a new RequestMeetupLocation object and copy fields, - values from RequestMeetupLocation object - * Adds the requestor as the meetup location moderator - * Sets the RequestMeetupLocation object's is_approved field to True. - """ - meetup_location_request = get_object_or_404( - RequestMeetupLocation, slug=self.kwargs['slug']) - new_meetup_location = MeetupLocation() - new_meetup_location.name = meetup_location_request.name - new_meetup_location.slug = meetup_location_request.slug - new_meetup_location.location = meetup_location_request.location - new_meetup_location.description = meetup_location_request.description - systersuser = meetup_location_request.user - new_meetup_location.leader = systersuser - - meetup_location_request.approved_by = get_object_or_404( - SystersUser, user=self.request.user) - meetup_location_request.is_approved = True - self.slug_meetup_location_request = meetup_location_request.slug - self.name_meetup_location_request = meetup_location_request.name - self.location_meetup_location_request = meetup_location_request.location - status, message, level = self.process_request() - messages.add_message(self.request, level, message) - if status == OK: - new_meetup_location.save() - new_meetup_location.members.add(systersuser) - new_meetup_location.moderators.add(systersuser) - meetup_location_request.save() - return reverse('about_meetup_location', kwargs={'slug': new_meetup_location.slug}) - else: - return reverse('new_meetup_location_requests') - - def process_request(self): - """If an error occurs during the creation of a new meetup location, this method returns the - status and message.""" - self.slug_meetup_location_values = MeetupLocation.objects.all( - ).values_list('slug', flat=True) - self.name_meetup_location_values = MeetupLocation.objects.all( - ).values_list('name', flat=True) - self.location_meetup_location_values = MeetupLocation.objects.all( - ).values_list('location', flat=True) - if self.location_meetup_location_request in self.location_meetup_location_values: - STATUS = LOCATION_ALREADY_EXISTS - return STATUS, LOCATION_ALREADY_EXISTS_MSG.format(self.location_meetup_location_request - ), messages.WARNING - elif self.slug_meetup_location_request in self.slug_meetup_location_values: - STATUS = SLUG_ALREADY_EXISTS - return STATUS, SLUG_ALREADY_EXISTS_MSG.format(self.slug_meetup_location_request),\ - messages.WARNING - elif self.name_meetup_location_request in self.name_meetup_location_values: - STATUS = NAME_ALREADY_EXISTS - return STATUS, NAME_ALREADY_EXISTS_MSG.format(self.name_meetup_location_request),\ - messages.WARNING - else: - STATUS = OK - return STATUS, SUCCESS_MSG, messages.INFO - - -class RejectMeetupLocationRequestView(LoginRequiredMixin, StaffuserRequiredMixin, DeleteView): - """Reject the new meetup location request Request""" - model = RequestMeetupLocation - template_name = "meetup/confirm_reject_request_meetup_location.html" - raise_exception = True - - def get_success_url(self, *args, **kwargs): - """Supply the success URL in case of a successful submit""" - messages.add_message(self.request, messages.INFO, - "Meetup Location request successfullly rejected!") - meetup_location_request = get_object_or_404( - RequestMeetupLocation, slug=self.kwargs['slug']) - meetup_location_request.delete() - return reverse('new_meetup_location_requests') - - -class MeetupLocationAboutView(MeetupLocationMixin, TemplateView): - """Meetup Location about view, show about description of Meetup Location""" - model = MeetupLocation - template_name = "meetup/about.html" - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) + return self.request.user.has_perm("meetup.reject_meetup_request") class AllUpcomingMeetupsView(ListView): @@ -388,76 +194,41 @@ def get_context_data(self, **kwargs): date__gte=datetime.date.today()).order_by('date', 'time') context = super(AllUpcomingMeetupsView, self).get_context_data(**kwargs) context['cities_list'] = City.objects.all() - context['meetup_locations'] = MeetupLocation.objects.all() context['meetup_list'] = meetup_list + g = GeoIP2() + client_ip, is_routable = get_client_ip(self.request) + if is_routable: + context['current_city'] = g.city(client_ip)['city'] + else: + context['current_city'] = g.city("google.com")['city'] return context -class MeetupLocationList(ListView): - """List all Meetup Locations""" - template_name = "meetup/list_location.html" - model = MeetupLocation - paginate_by = 20 - - def get_context_data(self, **kwargs): - context = super(MeetupLocationList, self).get_context_data(**kwargs) - context['meetup_list'] = Meetup.objects.filter( - date__gte=datetime.date.today()).order_by('date', 'time') - return context - - -class MeetupView(MeetupLocationMixin, DetailView): +class MeetupView(DetailView): """View details of a meetup, including date, time, venue, description, number of users who rsvp'd and comments.""" template_name = "meetup/meetup.html" - model = MeetupLocation + model = Meetup def get_context_data(self, **kwargs): """Add Meetup object, number of users who rsvp'd and comments to the context""" context = super(MeetupView, self).get_context_data(**kwargs) - self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug'], - meetup_location=self.object) - context['meetup'] = self.meetup + context['meetup'] = self.object context['comments'] = Comment.objects.filter( content_type=ContentType.objects.get(app_label='meetup', model='meetup'), - object_id=self.meetup.id, + object_id=self.object.id, is_approved=True).order_by('date_created') - coming_list = Rsvp.objects.filter(meetup=self.meetup, coming=True) - plus_one_list = Rsvp.objects.filter(meetup=self.meetup, plus_one=True) - not_coming_list = Rsvp.objects.filter(meetup=self.meetup, coming=False) + coming_list = Rsvp.objects.filter(meetup=self.object, coming=True) + plus_one_list = Rsvp.objects.filter(meetup=self.object, plus_one=True) + not_coming_list = Rsvp.objects.filter(meetup=self.object, coming=False) context['coming_no'] = len(coming_list) + len(plus_one_list) context['not_coming_no'] = len(not_coming_list) - context['share_message'] = self.meetup.title + " @systers_org " + \ - self.meetup.meetup_location.name + context['share_message'] = self.object.title + " @systers_org " return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.object - - -class MeetupLocationMembersView(MeetupLocationMixin, DetailView): - """Meetup Location members view, show members list of Meetup Location""" - model = MeetupLocation - template_name = "meetup/members.html" - paginate_by = 50 - - def get_context_data(self, **kwargs): - """Add list of members and moderators to the context""" - context = super(MeetupLocationMembersView, self).get_context_data(**kwargs) - moderator_list = self.meetup_location.moderators.all() - context['moderator_list'] = moderator_list - context['member_list'] = self.meetup_location.members.exclude(id__in=moderator_list) - return context - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.meetup_location - class AddMeetupView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequiredMixin, - PermissionRequiredMixin, MeetupLocationMixin, CreateView): + PermissionRequiredMixin, CreateView): """Add new meetup""" template_name = "meetup/add_meetup.html" model = Meetup @@ -468,31 +239,24 @@ class AddMeetupView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequire def get_success_url(self): """Redirect to meetup view page in case of successful submit""" - return reverse("view_meetup", kwargs={"slug": self.meetup_location.slug, - "meetup_slug": self.object.slug}) + return reverse("view_meetup", kwargs={"slug": self.object.slug}) def get_form_kwargs(self): - """Add request user and meetup location object to the form kwargs. - Used to autofill form fields with created_by and meetup_location without + """Add request user object to the form kwargs. + Used to autofill form fields with created_by without explicitly filling them up in the form.""" kwargs = super(AddMeetupView, self).get_form_kwargs() - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - kwargs.update({'created_by': self.request.user}) - kwargs.update({'meetup_location': self.meetup_location}) + kwargs.update({'created_by': self.request.user, + 'leader': self.request.user}) return kwargs - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - def check_permissions(self, request): - """Check if the request user has the permission to add a meetup to the meetup location. + """Check if the request user has the permission to add a meetup . The permission holds true for superusers.""" - return request.user.has_perm('meetup.add_meetup') + return request.user.has_perm('meetup.add_meetups') -class DeleteMeetupView(LoginRequiredMixin, PermissionRequiredMixin, MeetupLocationMixin, - DeleteView): +class DeleteMeetupView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView): """Delete existing Meetup""" template_name = "meetup/meetup_confirm_delete.html" model = Meetup @@ -500,20 +264,13 @@ class DeleteMeetupView(LoginRequiredMixin, PermissionRequiredMixin, MeetupLocati raise_exception = True def get_success_url(self): - """Redirect to meetup location's about page in case of successful deletion""" - self.get_meetup_location() - return reverse("about_meetup_location", - kwargs={"slug": self.meetup_location.slug}) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.meetup_location + """Redirect to upcoming meetups page in case of successful deletion""" + return reverse("upcoming_meetups") def check_permissions(self, request): - """Check if the request user has the permission to delete a meetup from the meetup - location. The permission holds true for superusers.""" - return request.user.has_perm('meetup.delete_meetup') + """Check if the request user has the permission to delete a meetup. + The permission holds true for superusers.""" + return request.user.has_perm('meetup.delete_meetups') class EditMeetupView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequiredMixin, @@ -529,8 +286,7 @@ class EditMeetupView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequir def get_success_url(self): """Redirect to meetup view page in case of successful submit""" - return reverse("view_meetup", kwargs={"slug": self.object.meetup_location.slug, - "meetup_slug": self.object.slug}) + return reverse("view_meetup", kwargs={"slug": self.object.slug}) def get_context_data(self, **kwargs): """Add Meetup and MeetupLocation objects to the context""" @@ -541,12 +297,12 @@ def get_context_data(self, **kwargs): return context def check_permissions(self, request): - """Check if the request user has the permission to edit a meetup from the meetup location. + """Check if the request user has the permission to edit a meetup. The permission holds true for superusers.""" - return request.user.has_perm('meetup.change_meetup') + return request.user.has_perm('meetup.change_meetups') -class UpcomingMeetupsView(MeetupLocationMixin, ListView): +class UpcomingMeetupsView(ListView): """List upcoming meetups of a meetup location""" template_name = "meetup/upcoming_meetups.html" model = Meetup @@ -555,18 +311,12 @@ class UpcomingMeetupsView(MeetupLocationMixin, ListView): def get_queryset(self, **kwargs): """Set ListView queryset to all the meetups whose date is equal to or greater than the current date""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - meetup_list = Meetup.objects.filter( - meetup_location=self.meetup_location, - date__gte=datetime.date.today()).order_by('date', 'time') + meetup_list = \ + Meetup.objects.filter(date__gte=datetime.date.today()).order_by('date', 'time') return meetup_list - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - -class PastMeetupListView(MeetupLocationMixin, ListView): +class PastMeetupListView(ListView): """List past meetups of a meetup location""" template_name = "meetup/past_meetups.html" model = Meetup @@ -574,348 +324,12 @@ class PastMeetupListView(MeetupLocationMixin, ListView): def get_queryset(self, **kwargs): """Set ListView queryset to all the meetups whose date is less than the current date""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - meetup_list = Meetup.objects.filter( - meetup_location=self.meetup_location, - date__lt=datetime.date.today()).order_by('date', 'time') + meetup_list = Meetup.objects.filter(date__lt=datetime.date.today()).order_by('date', 'time') return meetup_list - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - - -class MeetupLocationSponsorsView(MeetupLocationMixin, DetailView): - """View sponsors of a meetup location""" - template_name = "meetup/sponsors.html" - model = MeetupLocation - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - - -class RemoveMeetupLocationMemberView(LoginRequiredMixin, PermissionRequiredMixin, - MeetupLocationMixin, RedirectView): - """Remove a member from a meetup location""" - model = MeetupLocation - permanent = False - raise_exception = True - - def get_redirect_url(self, *args, **kwargs): - """Remove the member from 'member' and 'moderator' lists and redirect to the members page - of the meetup location""" - user = get_object_or_404(User, username=self.kwargs.get('username')) - systersuser = get_object_or_404(SystersUser, user=user) - moderators = self.meetup_location.moderators.all() - if systersuser in moderators and len(moderators) > 1: - self.meetup_location.moderators.remove(systersuser) - if systersuser not in self.meetup_location.moderators.all(): - self.meetup_location.members.remove(systersuser) - return reverse('members_meetup_location', kwargs={'slug': self.meetup_location.slug}) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - - def check_permissions(self, request): - """Check if the request user has the permission to remove a member from the meetup - location. The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('delete_meetup_location_member', self.meetup_location) - - -class AddMeetupLocationMemberView(FormValidMessageMixin, FormInvalidMessageMixin, - LoginRequiredMixin, PermissionRequiredMixin, - MeetupLocationMixin, UpdateView): - """Add new member to meetup location""" - template_name = "meetup/add_member.html" - model = MeetupLocation - form_class = AddMeetupLocationMemberForm - form_valid_message = (u"Member added Successfully") - form_invalid_message = ERROR_MSG - raise_exception = True - - def get_success_url(self): - """Redirect to the members page of the meetup location in case of successful addition""" - return reverse('members_meetup_location', kwargs={'slug': self.meetup_location.slug}) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - - def check_permissions(self, request): - """Check if the request user has the permission to add a member to the meetup location. - The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('add_meetup_location_member', self.meetup_location) - - -class RemoveMeetupLocationModeratorView(LoginRequiredMixin, PermissionRequiredMixin, - MeetupLocationMixin, RedirectView): - """Remove the 'moderator' status of a meetup location member""" - model = MeetupLocation - permanent = False - raise_exception = True - - def get_redirect_url(self, *args, **kwargs): - """Remove the member from the 'moderator' list and redirect to the members page of the - meetup location""" - user = get_object_or_404(User, username=self.kwargs.get('username')) - systersuser = get_object_or_404(SystersUser, user=user) - moderators = self.meetup_location.moderators.all() - if systersuser in moderators and len(moderators) > 1: - self.meetup_location.moderators.remove(systersuser) - return reverse('members_meetup_location', kwargs={'slug': self.meetup_location.slug}) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - - def check_permissions(self, request): - """Check if the request user has the permission to remove an moderator from the meetup - location. The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('delete_meetup_location_moderator', self.meetup_location) - - -class MakeMeetupLocationModeratorView(LoginRequiredMixin, PermissionRequiredMixin, - MeetupLocationMixin, RedirectView): - """Make a meetup location member an moderator of the location""" - model = MeetupLocation - permanent = False - raise_exception = True - - def get_redirect_url(self, *args, **kwargs): - """Add the member to the 'moderator' list and send her a notification email. Redirect to - the members page of the meetup location""" - user = get_object_or_404(User, username=self.kwargs.get('username')) - systersuser = get_object_or_404(SystersUser, user=user) - moderators = self.meetup_location.moderators.all() - if systersuser not in moderators: - self.meetup_location.moderators.add(systersuser) - notification.send([user], 'made_moderator', {'meetup_location': self.meetup_location}) - return reverse('members_meetup_location', kwargs={'slug': self.meetup_location.slug}) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - - def check_permissions(self, request): - """Check if the request user has the permission to add an moderator to the meetup - location. The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('add_meetup_location_moderator', self.meetup_location) - - -class JoinMeetupLocationView(LoginRequiredMixin, MeetupLocationMixin, RedirectView): - """Send a join request for a meetup location""" - model = MeetupLocation - permanent = False - raise_exception = True - - def get_redirect_url(self, *args, **kwargs): - """Redirect to meetup location's about page.""" - return reverse('about_meetup_location', kwargs={'slug': self.meetup_location.slug}) - - def get(self, request, *args, **kwargs): - """Display messages to the user as per the following conditions: - * if the user is not a meetup location member and has not requested to join the location - before, add the user's join request, display the corresponding message and send a - notification to all moderators - * if the user is not a meetup location member and has requested to join the location - before, display the corresponding message - * if the user is aleady a member of the meetup location, display the corresponding message - """ - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - user = get_object_or_404(User, username=self.kwargs.get('username')) - systersuser = get_object_or_404(SystersUser, user=user) - - join_requests = self.meetup_location.join_requests.all() - members = self.meetup_location.members.all() - moderators = [systers_user.user for systers_user in self.meetup_location.moderators.all()] - - if systersuser not in join_requests and systersuser not in members: - self.meetup_location.join_requests.add(systersuser) - msg = "Your request to join meetup location {0} has been sent. In a short while " \ - "someone will review your request." - messages.add_message(request, messages.SUCCESS, msg.format(self.meetup_location)) - notification.send(moderators, 'new_join_request', - {'meetup_location': self.meetup_location, - 'systersuser': systersuser}) - elif systersuser in join_requests: - msg = "You have already requested to join meetup location {0}. Please wait until " \ - "someone reviews your request." - messages.add_message(request, messages.WARNING, msg.format(self.meetup_location)) - elif systersuser in members: - msg = "You are already a member of meetup location {0}." - messages.add_message(self.request, messages.WARNING, msg.format(self.meetup_location)) - return super(JoinMeetupLocationView, self).get(request, *args, **kwargs) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - - -class MeetupLocationJoinRequestsView(LoginRequiredMixin, MeetupLocationMixin, DetailView): - """View all join requests for a meetup location""" - model = MeetupLocation - template_name = "meetup/join_requests.html" - paginated_by = 20 - - def get_context_data(self, **kwargs): - """Add all join requests to the context""" - context = super(MeetupLocationJoinRequestsView, self).get_context_data(**kwargs) - context['requests'] = self.object.join_requests.all() - return context - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.object - - -class ApproveMeetupLocationJoinRequestView(LoginRequiredMixin, PermissionRequiredMixin, - MeetupLocationMixin, RedirectView): - """Approve a join request for a meetup location""" - model = MeetupLocation - permanent = False - raise_exception = True - - def get_redirect_url(self, *args, **kwargs): - """Add the user to the members of the meetup location, send the user a notification and - redirect to meetup location's join request page""" - user = get_object_or_404(User, username=self.kwargs.get('username')) - systersuser = get_object_or_404(SystersUser, user=user) - self.meetup_location.members.add(systersuser) - self.meetup_location.join_requests.remove(systersuser) - notification.send([user], 'joined_meetup_location', - {'meetup_location': self.meetup_location}) - messages.success(self.request, 'Join request Approved.') - return reverse('join_requests_meetup_location', kwargs={'slug': self.meetup_location.slug}) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - - def check_permissions(self, request): - """Check if the request user has the permission to approve a join request for the meetup - location. The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('approve_meetup_location_joinrequest', self.meetup_location) - - -class RejectMeetupLocationJoinRequestView(LoginRequiredMixin, PermissionRequiredMixin, - MeetupLocationMixin, RedirectView): - """Reject a join request for a meetup location""" - model = MeetupLocation - permanent = False - raise_exception = True - - def get_redirect_url(self, *args, **kwargs): - """Delete the user's join request and redirect to meetup location's join request page""" - user = get_object_or_404(User, username=self.kwargs.get('username')) - systersuser = get_object_or_404(SystersUser, user=user) - self.meetup_location.join_requests.remove(systersuser) - messages.warning(self.request, 'Join Request Deleted.') - return reverse('join_requests_meetup_location', kwargs={'slug': self.meetup_location.slug}) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - - def check_permissions(self, request): - """Check if the request user has the permission to reject a join request for the meetup - location. The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('reject_meetup_location_joinrequest', self.meetup_location) - - -class AddMeetupLocationView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequiredMixin, - PermissionRequiredMixin, MeetupLocationMixin, - CreateView): - """Add new meetup location""" - template_name = "meetup/add_meetup_location.html" - model = MeetupLocation - slug_url_kwarg = "slug" - form_class = AddMeetupLocationForm - form_valid_message = (u"Meetup added Successfully") - form_invalid_message = ERROR_MSG - raise_exception = True - - def get_success_url(self): - """Redirect to the meetup location's about page in case of successful submission""" - return reverse("about_meetup_location", kwargs={"slug": self.object.slug}) - - def get_form_kwargs(self): - """Add request user to the form kwargs. - Used to autofill form fields with requestor without - explicitly filling them up in the form.""" - kwargs = super(AddMeetupLocationView, self).get_form_kwargs() - kwargs.update({'user': self.request.user}) - return kwargs - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.object - - def check_permissions(self, request): - """Check if the request user has the permission to add a meetup location. - The permission holds true for superusers.""" - self.systersuser = get_object_or_404(SystersUser, user=request.user) - return request.user.has_perm('meetup.add_meetuplocation') - - -class EditMeetupLocationView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequiredMixin, - PermissionRequiredMixin, MeetupLocationMixin, - UpdateView): - """Edit an existing meetup location""" - template_name = "meetup/edit_meetup_location.html" - model = MeetupLocation - form_class = EditMeetupLocationForm - form_valid_message = (u"Meetup Location Editted Successfully") - form_invalid_message = ERROR_MSG - raise_exception = True - - def get_success_url(self): - """Redirect to the meetup location's about page in case of successful submission""" - self.get_meetup_location() - return reverse("about_meetup_location", kwargs={"slug": self.meetup_location.slug}) - - def get_meetup_location(self, **kwargs): - """Add MeetupLocation object to the context""" - return self.meetup_location - - def check_permissions(self, request): - """Check if the request user has the permission to edit a meetup location. - The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('meetup.change_meetuplocation') - - -class DeleteMeetupLocationView(LoginRequiredMixin, PermissionRequiredMixin, MeetupLocationMixin, - DeleteView): - """Delete an existing meetup location""" - template_name = "meetup/meetup_location_confirm_delete.html" - model = MeetupLocation - raise_exception = True - - def get_success_url(self): - """Redirect to the list of meetup locations in case of successful deletion""" - return reverse("list_meetup_location") - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.object - - def check_permissions(self, request): - """Check if the request user has the permission to delete a meetup location. - The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('meetup.delete_meetuplocation') - class AddMeetupCommentView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequiredMixin, - MeetupLocationMixin, CreateView): + CreateView): """Add a comment to a Meetup""" template_name = "meetup/add_comment.html" model = Comment @@ -926,14 +340,12 @@ class AddMeetupCommentView(FormValidMessageMixin, FormInvalidMessageMixin, Login def get_success_url(self): """Redirect to the meetup view page in case of successful addition""" - return reverse("view_meetup", kwargs={"slug": self.meetup_location.slug, - "meetup_slug": self.meetup.slug}) + return reverse("view_meetup", kwargs={"slug": self.meetup.slug}) def get_form_kwargs(self): """Add meetup object and request user to the form kwargs. Used to autofill form fields with content_object and author without explicitly filling them up in the form.""" kwargs = super(AddMeetupCommentView, self).get_form_kwargs() - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) kwargs.update({'content_object': self.meetup}) kwargs.update({'author': self.request.user}) @@ -945,14 +357,9 @@ def get_context_data(self, **kwargs): context['meetup'] = self.meetup return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - class EditMeetupCommentView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequiredMixin, - PermissionRequiredMixin, MeetupLocationMixin, - UpdateView): + PermissionRequiredMixin, UpdateView): """Edit a meetup's comment""" template_name = "meetup/edit_comment.html" model = Comment @@ -964,9 +371,7 @@ class EditMeetupCommentView(FormValidMessageMixin, FormInvalidMessageMixin, Logi def get_success_url(self): """Redirect to the meetup view page in case of successful submission""" - self.get_meetup_location() - return reverse("view_meetup", kwargs={"slug": self.meetup_location.slug, - "meetup_slug": self.object.content_object.slug}) + return reverse("view_meetup", kwargs={"slug": self.object.content_object.slug}) def get_context_data(self, **kwargs): """Add Meetup object to the context""" @@ -974,11 +379,6 @@ def get_context_data(self, **kwargs): context['meetup'] = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.meetup_location - def check_permissions(self, request): """Check if the request user has the permission to edit a meetup comment.""" self.comment = get_object_or_404(Comment, pk=self.kwargs['comment_pk']) @@ -986,8 +386,7 @@ def check_permissions(self, request): return systersuser == self.comment.author -class DeleteMeetupCommentView(LoginRequiredMixin, PermissionRequiredMixin, MeetupLocationMixin, - DeleteView): +class DeleteMeetupCommentView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView): """Delete a meetup's comment""" template_name = "meetup/comment_confirm_delete.html" model = Comment @@ -996,9 +395,7 @@ class DeleteMeetupCommentView(LoginRequiredMixin, PermissionRequiredMixin, Meetu def get_success_url(self): """Redirect to the meetup view page in case of successful submission""" - self.get_meetup_location() - return reverse("view_meetup", kwargs={"slug": self.meetup_location.slug, - "meetup_slug": self.object.content_object.slug}) + return reverse("view_meetup", kwargs={"slug": self.object.content_object.slug}) def get_context_data(self, **kwargs): """Add Meetup object to the context""" @@ -1006,11 +403,6 @@ def get_context_data(self, **kwargs): context['meetup'] = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.meetup_location - def check_permissions(self, request): """Check if the request user has the permission to delete a meetup comment.""" self.comment = get_object_or_404(Comment, pk=self.kwargs['comment_pk']) @@ -1019,7 +411,7 @@ def check_permissions(self, request): class RsvpMeetupView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequiredMixin, - PermissionRequiredMixin, MeetupLocationMixin, CreateView): + CreateView): """RSVP for a meetup""" template_name = "meetup/rsvp_meetup.html" model = Rsvp @@ -1030,14 +422,12 @@ class RsvpMeetupView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequir def get_success_url(self): """Redirect to the meetup view page in case of successful submission""" - return reverse("view_meetup", kwargs={"slug": self.meetup_location.slug, - "meetup_slug": self.object.meetup.slug}) + return reverse("view_meetup", kwargs={"slug": self.object.meetup.slug}) def get_form_kwargs(self): """Add request user and meetup object to the form kwargs. Used to autofill form fields with user and meetup without explicitly filling them up in the form.""" kwargs = super(RsvpMeetupView, self).get_form_kwargs() - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) kwargs.update({'user': self.request.user}) kwargs.update({'meetup': self.meetup}) @@ -1052,18 +442,8 @@ def get_context_data(self, **kwargs): context['meetup'] = self.meetup return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - def check_permissions(self, request): - """Check if the request user has the permission to RSVP for a meetup. The permission - holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('add_meetup_rsvp', self.meetup_location) - - -class RsvpGoingView(LoginRequiredMixin, MeetupLocationMixin, ListView): +class RsvpGoingView(LoginRequiredMixin, ListView): """List of members whose rsvp status is 'coming'""" template_name = "meetup/rsvp_going.html" model = Rsvp @@ -1071,9 +451,7 @@ class RsvpGoingView(LoginRequiredMixin, MeetupLocationMixin, ListView): def get_queryset(self, **kwargs): """Set ListView queryset to all rsvps whose 'coming' attribute is set to True""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug'], - meetup_location=self.meetup_location) + self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) rsvp_list = Rsvp.objects.filter(meetup=self.meetup, coming=True) return rsvp_list @@ -1083,14 +461,9 @@ def get_context_data(self, **kwargs): context['meetup'] = self.meetup return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - class AddSupportRequestView(FormValidMessageMixin, FormInvalidMessageMixin, - LoginRequiredMixin, PermissionRequiredMixin, MeetupLocationMixin, - CreateView): + LoginRequiredMixin, CreateView): """Add a Support Request for a meetup""" template_name = "meetup/add_support_request.html" model = SupportRequest @@ -1101,14 +474,13 @@ class AddSupportRequestView(FormValidMessageMixin, FormInvalidMessageMixin, def get_success_url(self): """Redirect to the support request view page in case of successful submission""" - return reverse("view_support_request", kwargs={"slug": self.meetup_location.slug, - "meetup_slug": self.meetup.slug, "pk": self.object.pk}) + return reverse("view_support_request", + kwargs={"meetup_slug": self.meetup.slug, "pk": self.object.pk}) def get_form_kwargs(self): """Add request user and meetup object to the form kwargs. Used to autofill form fields with volunteer and meetup without explicitly filling them up in the form.""" kwargs = super(AddSupportRequestView, self).get_form_kwargs() - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) kwargs.update({'volunteer': self.request.user}) kwargs.update({'meetup': self.meetup}) @@ -1120,19 +492,9 @@ def get_context_data(self, **kwargs): context['meetup'] = self.meetup return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - - def check_permissions(self, request): - """Check if the request user has the permission to add a Support Request for a meetup. - The permission holds true for superusers.""" - return request.user.has_perm('meetup.add_supportrequest') - -class EditSupportRequestView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequiredMixin, - PermissionRequiredMixin, MeetupLocationMixin, - UpdateView): +class EditSupportRequestView(FormValidMessageMixin, FormInvalidMessageMixin, + LoginRequiredMixin, PermissionRequiredMixin, UpdateView): """Edit an existing support request""" template_name = "meetup/edit_support_request.html" model = SupportRequest @@ -1143,9 +505,8 @@ class EditSupportRequestView(FormValidMessageMixin, FormInvalidMessageMixin, Log def get_success_url(self): """Redirect to the support request view page in case of successful submission""" - self.get_meetup_location() - return reverse("view_support_request", kwargs={"slug": self.meetup_location.slug, - "meetup_slug": self.object.meetup.slug, "pk": self.object.pk}) + return reverse("view_support_request", + kwargs={"meetup_slug": self.object.meetup.slug, "pk": self.object.pk}) def get_context_data(self, **kwargs): """Add Meetup object to the context""" @@ -1154,19 +515,15 @@ def get_context_data(self, **kwargs): context['meetup'] = self.meetup return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.meetup_location - def check_permissions(self, request): """Check if the request user has the permission to edit a Support Request for a meetup. The permission holds true for superusers.""" - return request.user.has_perm('meetup.change_supportrequest') + systersuser = get_object_or_404(SystersUser, user=request.user) + self.suppportrequest = get_object_or_404(SupportRequest, pk=self.kwargs["pk"]) + return systersuser == self.suppportrequest.volunteer -class DeleteSupportRequestView(LoginRequiredMixin, PermissionRequiredMixin, MeetupLocationMixin, - DeleteView): +class DeleteSupportRequestView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView): """Delete existing Support Request""" template_name = "meetup/support_request_confirm_delete.html" model = SupportRequest @@ -1174,23 +531,18 @@ class DeleteSupportRequestView(LoginRequiredMixin, PermissionRequiredMixin, Meet def get_success_url(self): """Redirect to the meetup view page in case of successful submission""" - self.get_meetup_location() messages.success(self.request, 'Support Request Deleted.') - return reverse("view_meetup", kwargs={"slug": self.meetup_location.slug, - "meetup_slug": self.object.meetup.slug}) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return self.meetup_location + return reverse("view_meetup", kwargs={"slug": self.object.meetup.slug}) def check_permissions(self, request): """Check if the request user has the permission to delete a Support Request for a meetup. The permission holds true for superusers.""" - return request.user.has_perm('meetup.delete_supportrequest') + systersuser = get_object_or_404(SystersUser, user=request.user) + self.suppportrequest = get_object_or_404(SupportRequest, pk=self.kwargs["pk"]) + return systersuser == self.suppportrequest.volunteer -class SupportRequestView(MeetupLocationMixin, DetailView): +class SupportRequestView(DetailView): """View a support request""" template_name = "meetup/support_request.html" model = SupportRequest @@ -1206,12 +558,8 @@ def get_context_data(self, **kwargs): is_approved=True).order_by('date_created') return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - -class SupportRequestsListView(MeetupLocationMixin, ListView): +class SupportRequestsListView(ListView): """List support requests for a meetup""" template_name = "meetup/list_support_requests.html" model = SupportRequest @@ -1229,13 +577,8 @@ def get_context_data(self, **kwargs): context['meetup'] = self.meetup return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - -class UnapprovedSupportRequestsListView(LoginRequiredMixin, PermissionRequiredMixin, - MeetupLocationMixin, ListView): +class UnapprovedSupportRequestsListView(LoginRequiredMixin, PermissionRequiredMixin, ListView): """List unapproved support requests for a meetup""" template_name = "meetup/unapproved_support_requests.html" model = SupportRequest @@ -1243,7 +586,7 @@ class UnapprovedSupportRequestsListView(LoginRequiredMixin, PermissionRequiredMi def get_queryset(self, **kwargs): """Set ListView queryset to all unapproved support requests of the meetup""" - self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) + self.meetup = get_object_or_404(Meetup, slug=self.kwargs['slug']) supportrequest_list = SupportRequest.objects.filter( meetup=self.meetup, is_approved=False) return supportrequest_list @@ -1254,17 +597,12 @@ def get_context_data(self, **kwargs): context['meetup'] = self.meetup return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - def check_permissions(self, request): """Check if the request user has the permission to approve a support request.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('approve_support_request', self.meetup_location) + return request.user.has_perm('meetup.approve_support_request') -class ApproveSupportRequestView(LoginRequiredMixin, PermissionRequiredMixin, MeetupLocationMixin, +class ApproveSupportRequestView(LoginRequiredMixin, PermissionRequiredMixin, RedirectView): """Approve a support request for a meetup""" model = SupportRequest @@ -1278,24 +616,14 @@ def get_redirect_url(self, *args, **kwargs): support_request = get_object_or_404(SupportRequest, pk=self.kwargs['pk']) support_request.is_approved = True support_request.save() - notification.send([support_request.volunteer.user], 'support_request_approved', - {'meetup_location': self.meetup_location, 'meetup': self.meetup, - 'support_request': support_request}) - return reverse('unapproved_support_requests', kwargs={'slug': self.meetup_location.slug, - 'meetup_slug': self.meetup.slug}) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location + return reverse('unapproved_support_requests', kwargs={'slug': self.meetup.slug}) def check_permissions(self, request): """Check if the request user has the permission to approve a support request.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('approve_support_request', self.meetup_location) + return request.user.has_perm('meetup.approve_support_request') -class RejectSupportRequestView(LoginRequiredMixin, PermissionRequiredMixin, MeetupLocationMixin, - RedirectView): +class RejectSupportRequestView(LoginRequiredMixin, PermissionRequiredMixin, RedirectView): """Reject a support request for a meetup""" model = SupportRequest permanent = False @@ -1306,22 +634,15 @@ def get_redirect_url(self, *args, **kwargs): self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) support_request = get_object_or_404(SupportRequest, pk=self.kwargs['pk']) support_request.delete() - return reverse('unapproved_support_requests', kwargs={'slug': self.meetup_location.slug, - 'meetup_slug': self.meetup.slug}) - - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location + return reverse('unapproved_support_requests', kwargs={'slug': self.meetup.slug}) def check_permissions(self, request): """Check if the request user has the permission to reject a support request.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('reject_support_request', self.meetup_location) + return request.user.has_perm('meetup.reject_support_request') class AddSupportRequestCommentView(FormValidMessageMixin, FormInvalidMessageMixin, - LoginRequiredMixin, PermissionRequiredMixin, - MeetupLocationMixin, CreateView): + LoginRequiredMixin, CreateView): """Add a comment to a Support Request""" template_name = "meetup/add_comment.html" model = Comment @@ -1332,8 +653,9 @@ class AddSupportRequestCommentView(FormValidMessageMixin, FormInvalidMessageMixi def get_success_url(self): """Redirect to the support request view page in case of successful submission""" - return reverse('view_support_request', kwargs={'slug': self.meetup_location.slug, - 'meetup_slug': self.meetup.slug, 'pk': self.support_request.pk}) + return reverse('view_support_request', + kwargs={'meetup_slug': self.meetup.slug, + 'pk': self.support_request.pk}) def get_form_kwargs(self): """Add support request object and request user to the form kwargs. Used to autofill form @@ -1352,20 +674,10 @@ def get_context_data(self, **kwargs): context['support_request'] = self.support_request return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - return self.meetup_location - - def check_permissions(self, request): - """Check if the request user has the permission to add a comment to a Support Request. - The permission holds true for superusers.""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - return request.user.has_perm('add_support_request_comment', self.meetup_location) - class EditSupportRequestCommentView(FormValidMessageMixin, FormInvalidMessageMixin, LoginRequiredMixin, PermissionRequiredMixin, - MeetupLocationMixin, UpdateView): + UpdateView): """Edit a support request's comment""" template_name = "meetup/edit_comment.html" model = Comment @@ -1377,25 +689,20 @@ class EditSupportRequestCommentView(FormValidMessageMixin, FormInvalidMessageMix def get_success_url(self): """Redirect to the support request view page in case of successful submission""" - self.get_meetup_location() - return reverse("view_support_request", kwargs={"slug": self.meetup_location.slug, - "meetup_slug": self.meetup.slug, + self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) + self.support_request = get_object_or_404(SupportRequest, pk=self.kwargs['pk']) + return reverse("view_support_request", kwargs={"meetup_slug": self.meetup.slug, "pk": self.support_request.pk}) def get_context_data(self, **kwargs): """Add Meetup and SupportRequest objects to the context""" context = super(EditSupportRequestCommentView, self).get_context_data(**kwargs) + self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) + self.support_request = get_object_or_404(SupportRequest, pk=self.kwargs['pk']) context['meetup'] = self.meetup context['support_request'] = self.support_request return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) - self.support_request = get_object_or_404(SupportRequest, pk=self.kwargs['pk']) - return self.meetup_location - def check_permissions(self, request): """Check if the request user has the permission to edit a comment to a Support Request""" self.comment = get_object_or_404(Comment, pk=self.kwargs['comment_pk']) @@ -1404,7 +711,7 @@ def check_permissions(self, request): class DeleteSupportRequestCommentView(LoginRequiredMixin, PermissionRequiredMixin, - MeetupLocationMixin, DeleteView): + DeleteView): """Delete a support request's comment""" template_name = "meetup/comment_confirm_delete.html" model = Comment @@ -1413,25 +720,20 @@ class DeleteSupportRequestCommentView(LoginRequiredMixin, PermissionRequiredMixi def get_success_url(self): """Redirect to the support request view page in case of successful submission""" - self.get_meetup_location() - return reverse("view_support_request", kwargs={"slug": self.meetup_location.slug, - "meetup_slug": self.meetup.slug, + self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) + self.support_request = get_object_or_404(SupportRequest, pk=self.kwargs['pk']) + return reverse("view_support_request", kwargs={"meetup_slug": self.meetup.slug, "pk": self.support_request.pk}) def get_context_data(self, **kwargs): """Add Meetup and SupportRequest objects to the context""" context = super(DeleteSupportRequestCommentView, self).get_context_data(**kwargs) + self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) + self.support_request = get_object_or_404(SupportRequest, pk=self.kwargs['pk']) context['meetup'] = self.meetup context['support_request'] = self.support_request return context - def get_meetup_location(self): - """Add MeetupLocation object to the context""" - self.meetup_location = get_object_or_404(MeetupLocation, slug=self.kwargs['slug']) - self.meetup = get_object_or_404(Meetup, slug=self.kwargs['meetup_slug']) - self.support_request = get_object_or_404(SupportRequest, pk=self.kwargs['pk']) - return self.meetup_location - def check_permissions(self, request): """Check if the request user has the permission to edit a Support Request for a meetup""" self.comment = get_object_or_404(Comment, pk=self.kwargs['comment_pk']) @@ -1439,61 +741,6 @@ def check_permissions(self, request): return systersuser == self.comment.author -class CancelMeetupLocationJoinRequestView(LoginRequiredMixin, SingleObjectMixin, - RedirectView): - """Cancel a join request to a meetup location view""" - model = MeetupLocation - permanent = False - raise_exception = True - - # TODO: add `redirect_unauthenticated_users = True` when django-braces will - # reach version 1.5 - - def get_redirect_url(self, *args, **kwargs): - """Redirect to the page the user was previously on""" - return self.request.GET.get('current_url') - - def get(self, request, *args, **kwargs): - """Attempt to cancel user join request towards a meetup location - * if a SystersUser is already a member, add a warning message - * if there is no pending request, add a warning message - """ - user = get_object_or_404(User, username=self.kwargs.get('username')) - systersuser = get_object_or_404(SystersUser, user=user) - - join_requests = self.get_object().join_requests.all() - members = self.get_object().members.all() - - if systersuser not in members and systersuser in join_requests: - self.get_object().join_requests.remove(systersuser) - messages.add_message( - request, - messages.SUCCESS, - "Your request to join {0} meetup location was canceled.".format(self.get_object()) - ) - - elif systersuser in members: - messages.add_message( - request, - messages.WARNING, - "You are already a member of {0} meetup location. " - "There is no pending join request.".format( - self.get_object() - )) - - elif systersuser not in join_requests: - messages.add_message( - request, - messages.WARNING, - "There is no pending request to join {0} meetup location.".format(self.get_object()) - ) - else: - pass - # TODO: configure logging and log the unknown status - return super(CancelMeetupLocationJoinRequestView, self).get(request, *args, - **kwargs) - - class ApiForVmsView(APIView): @classmethod @@ -1517,7 +764,7 @@ def get(self, request): # fetching all meetups meetups = Meetup.objects.all().order_by('date') apiforvmsview = ApiForVmsView() - return(apiforvmsview.return_meetup_data(meetups)) + return (apiforvmsview.return_meetup_data(meetups)) @classmethod def post(self, request): @@ -1525,81 +772,50 @@ def post(self, request): # fetching all meetups whose id is greater than or equal to the date posted meetups = Meetup.objects.filter(pk__gte=ID).order_by('date') apiforvmsview = ApiForVmsView() - return(apiforvmsview.return_meetup_data(meetups)) + return (apiforvmsview.return_meetup_data(meetups)) class UpcomingMeetupsSearchView(ListView): - """Search Upcoming Meetups By Meetup Location, Date & Keyword and Filter by Date & - Distance""" + """Search Upcoming Meetups By Keyword and Filter Date and Distance""" template_name = "meetup/list_meetup.html" model = Meetup @csrf_exempt def post(self, request): if request.method == 'POST': - date = request.POST.get('date') - meetup_location = request.POST.get('meetup_location') keyword = request.POST.get('keyword') - selected_filter = request.POST.get('filter') location = request.POST.get('location') - if meetup_location == 'Meetup Location': - # when no meetup_location is selected from dropdown - meetup_location = '' - if date and meetup_location and keyword: - # search by date, meetup_location & keyword - searched_meetups = Meetup.objects.filter(Q(description__contains=keyword) | - Q(title__contains=keyword), date=date, - meetup_location__name=meetup_location) - elif date and meetup_location: - # search by date & meetup_location - searched_meetups = Meetup.objects.filter(date=date, - meetup_location__name=meetup_location) - elif date and keyword: - # search by date & keyword - searched_meetups = Meetup.objects.filter(Q(description__contains=keyword) | - Q(title__contains=keyword), date=date, - description__contains=keyword) - elif meetup_location and keyword: - # search by meetup_location & keyword - searched_meetups = Meetup.objects.filter(Q(description__contains=keyword) | - Q(title__contains=keyword), - meetup_location__name=meetup_location) - elif date: - # search by date - searched_meetups = Meetup.objects.filter(date=date) - elif meetup_location: - # search by meetup_location - searched_meetups = Meetup.objects.filter(meetup_location__name=meetup_location) - elif keyword: - # search by keyword - searched_meetups = Meetup.objects.filter(Q(description__contains=keyword) | - Q(title__contains=keyword)) - else: - searched_meetups = Meetup.objects.filter(date__gte=datetime.date.today()) - + searched_meetups = Meetup.objects.filter(Q(date__gte=datetime.date.today()), + Q(title__icontains=keyword)) results = list() unit = '' for meetup in searched_meetups: distance = '' - if selected_filter == 'distance': - # if user filters by distance - geolocator = Nominatim(timeout=6) - user_loc = (geolocator.geocode(location)) - user_point = Point((float)(user_loc.raw['lon']), (float)(user_loc.raw['lat'])) - meetup_loc = (geolocator.geocode(meetup.meetup_location.location)) - meetup_point = Point((float)(meetup_loc.raw['lon']), - (float)(meetup_loc.raw['lat'])) - distance = (int)(user_point.distance(meetup_point)) * 100 - results.sort(key=operator.itemgetter('distance')) - unit = 'kilometers from your location' + geolocator = Nominatim(user_agent="Anita-B Portal", timeout=6) + g = GeoIP2() + if location == "Current Location": + client_ip, is_routable = get_client_ip(request) + if is_routable: + lat, long = g.lat_lon(client_ip) + else: + lat, long = g.lat_lon("google.com") + user_point = Point(float(long), + float(lat)) + else: + user_loc = geolocator.geocode(location) + user_point = Point(float(user_loc.raw['lon']), float(user_loc.raw['lat'])) + meetup_loc = geolocator.geocode(meetup.meetup_location) + meetup_point = Point(float(meetup_loc.raw['lon']), + float(meetup_loc.raw['lat'])) + distance = int(user_point.distance(meetup_point)) * 100 + unit = 'kilometers from your location' results.append({'date': meetup.date, 'meetup': meetup.title, - 'location': meetup.meetup_location.name, - 'location_slug': meetup.meetup_location.slug, - 'meetup_slug': meetup.slug, 'distance': distance, - 'unit': unit}) + 'location': meetup.meetup_location.name, + 'meetup_slug': meetup.slug}) results.sort(key=operator.itemgetter('date')) - return JsonResponse({'search_results': results}, safe=False) + results.sort(key=operator.itemgetter('distance')) + return JsonResponse({'search_results': results, 'unit': unit}, safe=False) diff --git a/systers_portal/membership/migrations/0001_initial.py b/systers_portal/membership/migrations/0001_initial.py index 47e45666..a1fcc780 100644 --- a/systers_portal/membership/migrations/0001_initial.py +++ b/systers_portal/membership/migrations/0001_initial.py @@ -1,29 +1,22 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals +# Generated by Django 3.0.8 on 2020-07-24 20:45 -from django.db import models, migrations +from django.db import migrations, models class Migration(migrations.Migration): + initial = True + dependencies = [ - ('users', '0001_squashed_0003_auto_20160207_1550'), - ('community', '0006_auto_20150208_0818'), ] operations = [ migrations.CreateModel( name='JoinRequest', fields=[ - ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('date_created', models.DateTimeField(auto_now_add=True)), ('is_approved', models.BooleanField(default=False)), - ('approved_by', models.ForeignKey(related_name='approved_by', blank=True, to='users.SystersUser', null=True)), - ('community', models.ForeignKey(to='community.Community')), - ('user', models.ForeignKey(related_name='created_by', to='users.SystersUser')), ], - options={ - }, - bases=(models.Model,), ), ] diff --git a/systers_portal/membership/migrations/0002_auto_20200724_2045.py b/systers_portal/membership/migrations/0002_auto_20200724_2045.py new file mode 100644 index 00000000..814b9c86 --- /dev/null +++ b/systers_portal/membership/migrations/0002_auto_20200724_2045.py @@ -0,0 +1,33 @@ +# Generated by Django 3.0.8 on 2020-07-24 20:45 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('users', '0001_initial'), + ('community', '0001_initial'), + ('membership', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='joinrequest', + name='approved_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='approved_by', to='users.SystersUser'), + ), + migrations.AddField( + model_name='joinrequest', + name='community', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='community.Community'), + ), + migrations.AddField( + model_name='joinrequest', + name='user', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='created_by', to='users.SystersUser'), + ), + ] diff --git a/systers_portal/membership/models.py b/systers_portal/membership/models.py index 2f05b3c1..1052242b 100644 --- a/systers_portal/membership/models.py +++ b/systers_portal/membership/models.py @@ -41,10 +41,10 @@ def cancel_join_request(self, user, community): class JoinRequest(models.Model): """Model to represent a request to join a community by a user""" - user = models.ForeignKey(SystersUser, related_name='created_by') + user = models.ForeignKey(SystersUser, related_name='created_by', on_delete=models.CASCADE) approved_by = models.ForeignKey(SystersUser, blank=True, null=True, - related_name='approved_by') - community = models.ForeignKey(Community) + related_name='approved_by', on_delete=models.CASCADE) + community = models.ForeignKey(Community, on_delete=models.CASCADE) date_created = models.DateTimeField(auto_now_add=True) is_approved = models.BooleanField(default=False) diff --git a/systers_portal/membership/tests/test_forms.py b/systers_portal/membership/tests/test_forms.py index 5c61f60d..97ecd7a4 100644 --- a/systers_portal/membership/tests/test_forms.py +++ b/systers_portal/membership/tests/test_forms.py @@ -1,3 +1,4 @@ +from cities_light.models import Country, City from django import forms from django.contrib.auth.models import User from django.test import TestCase @@ -11,8 +12,11 @@ class TransferOwnershipFormTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_transfer_ownership_form(self): diff --git a/systers_portal/membership/tests/test_models.py b/systers_portal/membership/tests/test_models.py index c86dbb75..08e248ac 100644 --- a/systers_portal/membership/tests/test_models.py +++ b/systers_portal/membership/tests/test_models.py @@ -1,3 +1,4 @@ +from cities_light.models import Country, City from django.test import TestCase from django.contrib.auth.models import User @@ -10,10 +11,12 @@ class JoinRequestModelTestCase(TestCase): def setUp(self): self.user = User.objects.create(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, - admin=self. - systers_user) + order=1, location=location, + admin=self.systers_user) def test_unicode(self): """Test JoinRequest object string representation""" diff --git a/systers_portal/membership/tests/test_views.py b/systers_portal/membership/tests/test_views.py index 1a33faa8..13428258 100644 --- a/systers_portal/membership/tests/test_views.py +++ b/systers_portal/membership/tests/test_views.py @@ -1,5 +1,6 @@ +from cities_light.models import Country, City from django.contrib.auth.models import User, Group -from django.core.urlresolvers import reverse +from django.urls import reverse from django.test import TestCase from community.constants import USER_CONTENT_MANAGER @@ -12,8 +13,11 @@ class CommunityJoinRequestListViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_get_community_join_request_list_view(self): @@ -43,8 +47,11 @@ class ApproveCommunityJoinRequestViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_approve_community_join_request_view_redundant(self): @@ -124,8 +131,11 @@ class RejectCommunityJoinRequestViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_reject_community_join_request_view_redundant(self): @@ -179,8 +189,11 @@ class RequestJoinCommunityViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_request_join_community_view(self): @@ -241,8 +254,11 @@ class CancelCommunityJoinRequestView(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_cancel_community_join_request(self): @@ -295,8 +311,11 @@ class LeaveCommunityViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_leave_community(self): @@ -345,8 +364,11 @@ class TransferOwnershipViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_get_transfer_ownership_view(self): @@ -411,8 +433,11 @@ class RemoveCommunityMemberViewTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='foo', password='foobar') self.systers_user = SystersUser.objects.get(user=self.user) + country = Country.objects.create(name='Bar', continent='AS') + location = City.objects.create(name='Foo', display_name='Foo', + country=country) self.community = Community.objects.create(name="Foo", slug="foo", - order=1, + order=1, location=location, admin=self.systers_user) def test_remove_community_member_view(self): diff --git a/systers_portal/membership/views.py b/systers_portal/membership/views.py index 8134f517..aeb4fc48 100644 --- a/systers_portal/membership/views.py +++ b/systers_portal/membership/views.py @@ -1,6 +1,6 @@ from django.contrib import messages from django.contrib.auth.models import User -from django.core.urlresolvers import reverse +from django.urls import reverse from django.shortcuts import get_object_or_404 from django.views.generic import RedirectView, ListView, FormView from django.views.generic.detail import SingleObjectMixin diff --git a/systers_portal/static/css/style.css b/systers_portal/static/css/style.css index 1792c47a..d6fc5f89 100755 --- a/systers_portal/static/css/style.css +++ b/systers_portal/static/css/style.css @@ -16,12 +16,12 @@ margin-bottom: 15px; } -.mr4 { - margin-right: 4px; +.mr16 { + margin-right: 16px; } -.ml15 { - margin-left: 15px; +.ml16 { + margin-left: 16px; } /* Sticky footer styles @@ -352,7 +352,7 @@ input { width: 30%; } -#meetup-location-input,#location-input { +#location-input { width: 15%; font-style: italic; font-family: 'Cairo'; @@ -626,7 +626,7 @@ table.decoration-none tr a { font-size: 1.0em; line-height: 1.0em; } - + .edit .delete { background-color: #fff; color: black; @@ -638,7 +638,7 @@ table.decoration-none tr a { .commentbox .details{ text-decoration: none; - + /* webkit-text-size-adjust: 100%;*/ } @@ -741,3 +741,43 @@ table.decoration-none tr a { display: none; } } +input[id=form1] { + width: 100%; + height: 40px; +} + + +.thumbnail { + background-color: #F0FFFF; +} + +input[id=keyword-input]{ + height: 30px; + font-family: 'Cairo'; + background-color: white; + border-bottom: 1px solid black; +} + +select[id=location]{ + height: 30px; + font-family: 'Cairo'; + background-color: white; + border-left: none; + border-right: none; + border-top: none; +} + +input[id=go-btn]{ + height:30px; + font-family: 'Cairo'; +} + +li[id=nav-menu]:hover{ + background-color:#54bceb; +} + +@media only screen and (min-width: 768px) { + .dropdown:hover .dropdown-menu { + display: block; + } +} diff --git a/systers_portal/static/js/community-search.js b/systers_portal/static/js/community-search.js new file mode 100644 index 00000000..182a522b --- /dev/null +++ b/systers_portal/static/js/community-search.js @@ -0,0 +1,26 @@ +const input = $("#form1") +const result_div = $('#cards') +const endpoint = '/community/search' +const delay_by_in_ms =300 +let scheduled_function = false + +let ajax_call = function (endpoint, request_parameters) { + $.getJSON(endpoint, request_parameters) + .done(response => { + result_div.fadeTo('fast', 0).promise().then(() => { + result_div.html(response['html']) + result_div.fadeTo('fast', 1) + + }) + }) +} +input.on('keyup', function () { + + const request_parameters = { + query: $(this).val() + } + if (scheduled_function) { + clearTimeout(scheduled_function) + } + scheduled_function = setTimeout(ajax_call, delay_by_in_ms, endpoint, request_parameters) +}) diff --git a/systers_portal/static/js/search_menu.js b/systers_portal/static/js/search_menu.js index 4f51621f..5f6761bc 100644 --- a/systers_portal/static/js/search_menu.js +++ b/systers_portal/static/js/search_menu.js @@ -18,18 +18,12 @@ function getCookie(name) { // Getting data from the search bars $("#go-btn").click(function() { - var MeetupLocation = document.getElementById("meetup-location-input").options[document.getElementById("meetup-location-input").selectedIndex].text; - var SelectedDate = document.getElementById("date-input").value; - var Keyword = document.getElementById("keyword-input").value; - var SelectedFilter = document.getElementById("myList").value; - var Location = document.getElementById("location-input").options[document.getElementById("location-input").selectedIndex].text; - var csrftoken = getCookie("csrftoken"); - var Data = { - "csrfmiddlewaretoken": csrftoken, - "meetup_location": MeetupLocation, - "date": SelectedDate, + let Keyword = document.getElementById("keyword-input").value; + let Location = document.getElementById("location").options[document.getElementById("location").selectedIndex].text; + let csrftoken = getCookie("csrftoken"); + let Data = { + "csrfmiddlewaretoken": csrftoken, "keyword": Keyword, - "filter" : SelectedFilter, "location": Location }; $.ajax({ @@ -37,26 +31,32 @@ $("#go-btn").click(function() { url: "search/", data: Data, success(a){ - var x = ""; + let x=""; + if(a.search_results.length==0){ + x = `

No Meetups Found

`; + } + else{ + x = `
`; for(var i of a.search_results){ - x += "
"+i.location +""+i.date+"\n" + - "
"+i.distance+" "+i.unit+"
"; + let link = `../${i.meetup_slug}/`; + x = x + `
+
+
+

${i.meetup}

+

${i.date}

+
${i.location}
+
${i.distance} ${a.unit}
+

+ Checkout +

+
+
+
`; + } + x = x + `
`; } $("#meetups-list").html(x); }, dataType:"json", }); }); - -// Hiding the location bar until distance filter is selected -$("#myList").change(function(){ - var SelectedFilter = document.getElementById("myList").value; - // If date filter is selected - if(SelectedFilter === "date"){ - $("#location").addClass("hidden"); - }else{ - $("#location").removeClass("hidden"); - } -}); diff --git a/systers_portal/systers_portal/settings/base.py b/systers_portal/systers_portal/settings/base.py index 3ff27ecf..203df2af 100644 --- a/systers_portal/systers_portal/settings/base.py +++ b/systers_portal/systers_portal/settings/base.py @@ -12,6 +12,7 @@ import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) +GOOGLE_MAPS_API_KEY = os.environ.get('GOOGLE_MAPS_API_KEY') # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ @@ -26,7 +27,6 @@ # Application definition INSTALLED_APPS = ( - 'djangocms_admin_style', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', @@ -57,7 +57,7 @@ 'pinax.notifications', ) -MIDDLEWARE_CLASSES = ( +MIDDLEWARE = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', @@ -66,7 +66,7 @@ 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.contrib.admindocs.middleware.XViewMiddleware', -) +] AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', @@ -164,3 +164,5 @@ # Django Crispy Forms configuration CRISPY_TEMPLATE_PACK = 'bootstrap3' + +GEOIP_PATH = os.path.join(BASE_DIR, "GeoLite2-City_20200616/GeoLite2-City.mmdb") diff --git a/systers_portal/systers_portal/urls.py b/systers_portal/systers_portal/urls.py index e04fe466..b04b7b46 100644 --- a/systers_portal/systers_portal/urls.py +++ b/systers_portal/systers_portal/urls.py @@ -23,7 +23,7 @@ url(r'^community/', include('membership.urls')), url(r'^meetup/', include('meetup.urls')), url(r'^users/', include('users.urls')), - url(r'^admin/', include(admin.site.urls)), + url(r'^admin/', admin.site.urls), url(r'^logout/', Logout.as_view(), name='logout'), url(r'^accounts/', include('allauth.urls')), url(r'^ckeditor/upload/', login_required(views), diff --git a/systers_portal/templates/account/login.html b/systers_portal/templates/account/login.html index 4bd81caa..e4019f6a 100644 --- a/systers_portal/templates/account/login.html +++ b/systers_portal/templates/account/login.html @@ -7,35 +7,34 @@ {% load crispy_forms_tags %} {% block content %} {% load socialaccount %} -{% load staticfiles %} -
- -