internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: akvo/akvo-rsr

Issue:
Project editor doesn't handle 404's
I accidentally tried [this project editor link](http://rsr.akvo.org/en/myrsr/project_editor/2867/). The problem is that there is no project with ID 2867. This should result in a 404, but instead we get a 500 😢 


Discussion:

Resolving patch:
diff --git a/akvo/rsr/views/my_rsr.py b/akvo/rsr/views/my_rsr.py
--- a/akvo/rsr/views/my_rsr.py
+++ b/akvo/rsr/views/my_rsr.py
@@ -274,7 +274,7 @@ def project_editor(request, project_id):
             'primary_organisation',
         ).get(pk=project_id)
     except Project.DoesNotExist:
-        return Http404
+        raise Http404('No project exists with the given id.')
 
     if (not request.user.has_perm('rsr.change_project', project) or project.iati_status in Project.EDIT_DISABLED) and not \
             (request.user.is_superuser or request.user.is_admin):


Test patch:
Repository: akvo/akvo-rsr

Issue:
CI should check for missing migrations and fail



Discussion:

Resolving patch:
diff --git a/akvo/rsr/migrations/0123_periodactualvalue_perioddisaggregation.py b/akvo/rsr/migrations/0123_periodactualvalue_perioddisaggregation.py
new file mode 100644
--- /dev/null
+++ b/akvo/rsr/migrations/0123_periodactualvalue_perioddisaggregation.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('rsr', '0122_auto_20180112_1454'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='PeriodActualValue',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('measure', models.CharField(max_length=1)),
+                ('value', models.IntegerField()),
+                ('numerator', models.IntegerField()),
+                ('denominator', models.IntegerField()),
+            ],
+            options={
+                'db_table': 'rsr_indicator_period_actual_value',
+                'managed': False,
+            },
+            bases=(models.Model,),
+        ),
+        migrations.CreateModel(
+            name='PeriodDisaggregation',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('dimension_name', models.CharField(max_length=100)),
+                ('dimension_value', models.CharField(max_length=100)),
+                ('value', models.IntegerField()),
+                ('numerator', models.IntegerField()),
+                ('denominator', models.IntegerField()),
+            ],
+            options={
+                'db_table': 'rsr_indicator_period_disaggregation',
+                'managed': False,
+            },
+            bases=(models.Model,),
+        ),
+    ]


Test patch:
diff --git a/akvo/rsr/tests/rest/migration_data.py b/akvo/rsr/tests/rest/migration_data.py
--- a/akvo/rsr/tests/rest/migration_data.py
+++ b/akvo/rsr/tests/rest/migration_data.py
@@ -22,6 +22,7 @@
   <user>1</user>
   <photo_credit>Da credz</photo_credit>
   <language>en</language>
+  <event_date>2018-01-16</event_date>
   <photo_caption>Da caption</photo_caption>
   <title>Foo</title>
   <project>4</project>
Repository: akvo/akvo-rsr

Issue:
Script to create a draft of the release notes for a milestone



Discussion:

Resolving patch:
diff --git a/scripts/devhelpers/release_notes.py b/scripts/devhelpers/release_notes.py
new file mode 100755
--- /dev/null
+++ b/scripts/devhelpers/release_notes.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+"""A script to generate the initial draft of release notes for a milestone.
+
+Usage:
+
+    {executable} <MILESTONE_ID>
+
+"""
+
+import requests
+
+URL = 'https://api.github.com/repos/akvo/akvo-rsr/issues?milestone={milestone}&state=closed'
+RELEASE_NOTES = """
+## New and noteworthy
+
+{features}
+
+## Resolved issues
+
+{bugs}
+
+## Code maintenance
+
+{chores}
+"""
+
+LABELS = {
+    'bugs': 'Bug',
+    'chores': 'Chore',
+    'features': None,
+}
+
+
+def get_issues(milestone):
+    """Return the issues in the milestone."""
+    url = URL.format(milestone=milestone)
+    entries = requests.get(url).json()
+    issues = [entry for entry in entries if 'pull_request' not in entry]
+    return issues
+
+
+def format_issue(issue):
+    return '- {title} [#{number}]({url})'.format(**issue)
+
+
+def format_issues(issues):
+    return '\n\n'.join(map(format_issue, issues))
+
+
+def issue_labels(issue):
+    return set([label['name'] for label in issue['labels']])
+
+
+def filter_issues(issues, label, labels):
+    other_labels = set(labels) - {label}
+    if label is None:
+        issues_ = [
+            issue for issue in issues
+            if not other_labels.intersection(issue_labels(issue))
+        ]
+    else:
+        issues_ = [
+            issue for issue in issues
+            if label in issue_labels(issue)
+        ]
+
+    return issues_
+
+
+def release_notes(issues):
+    grouped_issues = {
+        key: format_issues(filter_issues(issues, label, LABELS.values()))
+        for key, label in LABELS.items()
+    }
+    return RELEASE_NOTES.format(**grouped_issues)
+
+
+def main(milestone):
+    issues = get_issues(milestone)
+    print(release_notes(issues))
+
+
+if __name__ == '__main__':
+    import sys
+    if len(sys.argv) != 2:
+        sys.exit(__doc__.format(executable=sys.argv[0]))
+
+    milestone = sys.argv[1]
+    main(milestone)


Test patch:
Repository: akvo/akvo-rsr

Issue:
Updates can be posted to the wrong project
A user that can post updates to at least one project can with some clever data manipulation post updates to any project.


Discussion:

Resolving patch:
diff --git a/akvo/rsr/forms.py b/akvo/rsr/forms.py
--- a/akvo/rsr/forms.py
+++ b/akvo/rsr/forms.py
@@ -326,8 +326,8 @@ class ProjectUpdateForm(forms.ModelForm):
         'maxlength': '75',
         'placeholder': _(u'Video credit'),
     }))
-    latitude = forms.FloatField(widget=forms.HiddenInput())
-    longitude = forms.FloatField(widget=forms.HiddenInput())
+    latitude = forms.FloatField(initial=0, widget=forms.HiddenInput())
+    longitude = forms.FloatField(initial=0, widget=forms.HiddenInput())
 
     class Meta:
         model = ProjectUpdate
diff --git a/akvo/rsr/views/project.py b/akvo/rsr/views/project.py
--- a/akvo/rsr/views/project.py
+++ b/akvo/rsr/views/project.py
@@ -410,6 +410,8 @@ def set_update(request, project_id, edit_mode=False, form_class=ProjectUpdateFor
         raise PermissionDenied
 
     if request.method == 'POST':
+        if not allow_update:
+            raise PermissionDenied
         updateform = form_class(request.POST, request.FILES, instance=update)
         if updateform.is_valid():
             if update:


Test patch:
Repository: akvo/akvo-rsr

Issue:
My RSR restructuring
A project becomes to entry point to its: update, results, narrative summaries, reports.


Discussion:

Resolving patch:
diff --git a/akvo/urls.py b/akvo/urls.py
--- a/akvo/urls.py
+++ b/akvo/urls.py
@@ -103,6 +103,11 @@
     url(r'^myrsr/$',
         'akvo.rsr.views.my_rsr.my_rsr', name='my_rsr'),
 
+    url(r'^myrsr/project/(?P<project_id>\d+)/$',
+        'akvo.rsr.views.my_rsr.my_results',
+        kwargs=dict(template='myrsr/project.html'),
+        name='project-edit'),
+
     url(r'^myrsr/details/$',
         'akvo.rsr.views.my_rsr.my_details', name='my_details'),
 


Test patch:
Repository: akvo/akvo-rsr

Issue:
When logged in landing page should be "myRSR"



Discussion:

Resolving patch:
diff --git a/akvo/rsr/views/__init__.py b/akvo/rsr/views/__init__.py
--- a/akvo/rsr/views/__init__.py
+++ b/akvo/rsr/views/__init__.py
@@ -11,5 +11,7 @@
 
 
 def index(request):
-    """."""
-    return HttpResponseRedirect(reverse('project-directory', args=[]))
+    """Redirect user to project directory or My RSR."""
+
+    redirect_url = 'project-directory' if request.user.is_anonymous() else 'my_rsr'
+    return HttpResponseRedirect(reverse(redirect_url, args=[]))


Test patch:
Repository: akvo/akvo-rsr

Issue:
Alphabetise the list of partners on the Funding tab of the project page 
The list of partners on the Funding tab of the project page should follow the same ordering of the 'Project partners' tab, which is alphabetised: 

<img width="1204" alt="screen shot 2018-03-02 at 15 43 00" src="https://user-images.githubusercontent.com/26227538/36904263-879df6f6-1e30-11e8-9405-2602d2e53f31.png">



Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/project.py b/akvo/rsr/models/project.py
--- a/akvo/rsr/models/project.py
+++ b/akvo/rsr/models/project.py
@@ -1115,7 +1115,7 @@ def partners_info(self):
 
     def funding_partnerships(self):
         "Return the Partnership objects associated with the project that have funding information"
-        return self.partnerships.filter(iati_organisation_role=Partnership.IATI_FUNDING_PARTNER)
+        return self.partnerships.filter(iati_organisation_role=Partnership.IATI_FUNDING_PARTNER).order_by('organisation__name')
 
     def show_status_large(self):
         "Show the current project status with background"


Test patch:
Repository: akvo/akvo-rsr

Issue:
File upload fails when filename is too long
When uploading a file in an indicator period update in the results framework, the upload fails if the file name is too long (somewhere around 50 characters, depending on number of spaces etc in the file name). This is the case both for images and other files.




Discussion:

Resolving patch:
diff --git a/akvo/rsr/migrations/0124_auto_20180309_0923.py b/akvo/rsr/migrations/0124_auto_20180309_0923.py
new file mode 100644
--- /dev/null
+++ b/akvo/rsr/migrations/0124_auto_20180309_0923.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import sorl.thumbnail.fields
+import akvo.rsr.models.result.utils
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('rsr', '0123_periodactualvalue_perioddisaggregation'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='indicatorperioddata',
+            name='file',
+            field=models.FileField(upload_to=akvo.rsr.models.result.utils.file_path, max_length=255, verbose_name='file', blank=True),
+            preserve_default=True,
+        ),
+        migrations.AlterField(
+            model_name='indicatorperioddata',
+            name='photo',
+            field=sorl.thumbnail.fields.ImageField(upload_to=akvo.rsr.models.result.utils.image_path, max_length=255, verbose_name='photo', blank=True),
+            preserve_default=True,
+        ),
+    ]
diff --git a/akvo/rsr/models/result/indicator_period_data.py b/akvo/rsr/models/result/indicator_period_data.py
--- a/akvo/rsr/models/result/indicator_period_data.py
+++ b/akvo/rsr/models/result/indicator_period_data.py
@@ -65,8 +65,8 @@ class IndicatorPeriodData(TimestampsMixin, models.Model):
     status = ValidXMLCharField(_(u'status'), max_length=1, choices=STATUSES, db_index=True,
                                default=STATUS_DRAFT_CODE)
     text = ValidXMLTextField(_(u'text'), blank=True)
-    photo = ImageField(_(u'photo'), blank=True, upload_to=image_path)
-    file = models.FileField(_(u'file'), blank=True, upload_to=file_path)
+    photo = ImageField(_(u'photo'), blank=True, upload_to=image_path, max_length=255)
+    file = models.FileField(_(u'file'), blank=True, upload_to=file_path, max_length=255)
     update_method = ValidXMLCharField(_(u'update method'), blank=True, max_length=1,
                                       choices=UPDATE_METHODS, db_index=True, default='W')
 


Test patch:
Repository: akvo/akvo-rsr

Issue:
Adding many partners in one go generates error
Veerle reports getting an error when saving a lot of partners in the project editor in one go. She tried to enter around 10 partners, most with two roles and some with three. When she saved, she got the "Something went wrong while saving" error. She then saved again in the hope of the save working, but got the same reply a number of times.

After reloading, it was discovered the partners had in fact been saved, probably once for each press of the save button, resulting in a huge list of duplicated partners.


Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/partnership.py b/akvo/rsr/models/partnership.py
--- a/akvo/rsr/models/partnership.py
+++ b/akvo/rsr/models/partnership.py
@@ -198,8 +198,10 @@ def __unicode__(self):
 
     def clean(self):
         # Don't allow multiple reporting organisations
+        Project = models.get_model('rsr', 'project')
+        project = Project.objects.get(id=self.project_id)
         if self.iati_organisation_role == self.IATI_REPORTING_ORGANISATION:
-            reporting_orgs = self.project.partnerships.filter(
+            reporting_orgs = project.partnerships.filter(
                 iati_organisation_role=self.IATI_REPORTING_ORGANISATION
             )
 
@@ -220,5 +222,7 @@ def delete(self, *args, **kwargs):
     def set_primary_organisation(self):
         # Check which organisation should be set to the primary organisation of the project
         # This is done to get better performance on the project list page
-        self.project.primary_organisation = self.project.find_primary_organisation()
-        self.project.save(update_fields=['primary_organisation'])
+        Project = models.get_model('rsr', 'project')
+        project = Project.objects.get(id=self.project_id)
+        project.primary_organisation = project.find_primary_organisation()
+        project.save(update_fields=['primary_organisation'])
diff --git a/akvo/rsr/signals.py b/akvo/rsr/signals.py
--- a/akvo/rsr/signals.py
+++ b/akvo/rsr/signals.py
@@ -304,8 +304,10 @@ def update_project_funding(sender, **kwargs):
     # kwargs['raw'] is True when we're running manage.py loaddata
     if not kwargs.get('raw', False):
         try:
-            kwargs['instance'].project.update_funds()
-            kwargs['instance'].project.update_funds_needed()
+            Project = get_model('rsr', 'project')
+            project = Project.objects.get(id=kwargs['instance'].project_id)
+            project.update_funds()
+            project.update_funds_needed()
         except ObjectDoesNotExist:
             # this happens when a project is deleted, and thus any invoices linked to it go the
             # same way.


Test patch:
Repository: akvo/akvo-rsr

Issue:
IATI export for project editors
Project editors are not able to export an IATI file although they have the interface.



Discussion:
According to [the support article](https://akvorsr.supporthero.io/article/show/user-roles-and-permissions), Project Editors should have the permissions to add an IATI export. 

But when trying to add an IATI export as a Project Editor, you get a 403.


Resolving patch:
diff --git a/akvo/rsr/models/__init__.py b/akvo/rsr/models/__init__.py
--- a/akvo/rsr/models/__init__.py
+++ b/akvo/rsr/models/__init__.py
@@ -353,7 +353,7 @@
 rules.add_perm('rsr.change_projectdocument', is_rsr_admin | is_org_admin | is_org_project_editor)
 rules.add_perm('rsr.delete_projectdocument', is_rsr_admin | is_org_admin | is_org_project_editor)
 
-rules.add_perm('rsr.add_iatiexport', is_rsr_admin | is_org_admin)
+rules.add_perm('rsr.add_iatiexport', is_rsr_admin | is_org_admin | is_org_project_editor)
 rules.add_perm('rsr.change_iatiexport', is_rsr_admin | is_org_admin)
 rules.add_perm('rsr.delete_iatiexport', is_rsr_admin | is_org_admin)
 


Test patch:
Repository: akvo/akvo-rsr

Issue:
Add current language when calling the report server
If the UI would pass the current language/locale on the URL we could make reports that adapt to it.
This query parameter needs to start with p_. I suggest p_languageCode or p_lang.



Discussion:
This is best done in the URL rewiring done in nginx
Actually, the URLs in the rsr_reports table are not subject to the ususal Django language-magic, so thre needs to be a language token that is replaced just as for project or dates.

Resolving patch:
diff --git a/akvo/rsr/admin.py b/akvo/rsr/admin.py
--- a/akvo/rsr/admin.py
+++ b/akvo/rsr/admin.py
@@ -1526,8 +1526,16 @@ class IndicatorPeriodDataAdmin(admin.ModelAdmin):
 admin.site.register(get_model('rsr', 'IndicatorPeriodData'), IndicatorPeriodDataAdmin)
 
 
+class ReportAdminForm(forms.ModelForm):
+    class Meta:
+        model = get_model('rsr', 'Report')
+        widgets = {
+            'url': forms.Textarea(attrs={'rows': 2, 'style': 'width: 80%'})
+        }
+
 class ReportAdmin(admin.ModelAdmin):
     model = get_model('rsr', 'Report')
+    form = ReportAdminForm
     save_as = True
     filter_horizontal = ('organisations',)
 
diff --git a/akvo/rsr/models/report.py b/akvo/rsr/models/report.py
--- a/akvo/rsr/models/report.py
+++ b/akvo/rsr/models/report.py
@@ -14,9 +14,13 @@
 
 
 PARAMETER_REGEX = re.compile('{(.*?)}')
-ALLOWED_PARAMETERS = {'project', 'organisation', 'format', 'start_date', 'end_date'}
+ALLOWED_PARAMETERS = {
+    'project', 'organisation', 'format', 'start_date', 'end_date', 'language_code'
+}
 MANDATORY_PARAMETERS = {'format'}
 
+NEWLINE_REGEX = re.compile('.*\n.*')
+
 
 class ReportFormat(models.Model):
     name = ValidXMLCharField(_('name'), max_length=30, unique=True)
@@ -36,7 +40,8 @@ class Report(models.Model):
     url = ValidXMLCharField(
         _(u'url'),
         max_length=200,
-        help_text=_(u'Enter the parametrized path for downloading the report'),
+        help_text=_(u'Enter the parametrized path for downloading the report. NOTE: one line only '
+                    u'even if the input field allows for more!'),
     )
     formats = models.ManyToManyField(ReportFormat)
     organisations = models.ManyToManyField('Organisation', blank=True)
@@ -45,6 +50,10 @@ class Report(models.Model):
     def parameters(self):
         return sorted(PARAMETER_REGEX.findall(self.url))
 
+    @property
+    def multiple_lines(self):
+        return len(NEWLINE_REGEX.findall(self.url)) > 0
+
     def __unicode__(self):
         return u'{}'.format(self.name)
 
@@ -67,6 +76,11 @@ def clean(self, *args, **kwargs):
                 'These parameters are not allowed in URL: {}'.format(additional_parameters)
             )
 
+        if self.multiple_lines:
+            raise ValidationError(
+                'The URL template must be a single line.'
+            )
+
         super(Report, self).clean(*args, **kwargs)
 
     class Meta:


Test patch:
Repository: akvo/akvo-rsr

Issue:
Org admin should be able to perform M&E manager actions in Results UI
Org admins should also be included when checking if a user is capable of performing 'M&E Manager actions'


Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/__init__.py b/akvo/rsr/models/__init__.py
--- a/akvo/rsr/models/__init__.py
+++ b/akvo/rsr/models/__init__.py
@@ -212,6 +212,7 @@
 rules.add_perm('rsr.add_indicatorperiod', is_rsr_admin | is_org_admin | is_org_project_editor)
 rules.add_perm('rsr.change_indicatorperiod', is_rsr_admin | is_org_admin | is_org_project_editor)
 rules.add_perm('rsr.delete_indicatorperiod', is_rsr_admin | is_org_admin | is_org_project_editor)
+rules.add_perm('rsr.do_me_manager_actions', is_rsr_admin | is_org_admin | is_org_me_manager)
 
 rules.add_perm('rsr.view_indicatorperioddata', is_rsr_admin | is_org_admin | is_org_me_manager)
 rules.add_perm('rsr.add_indicatorperioddata', is_rsr_admin | is_org_admin | is_org_project_editor)
diff --git a/akvo/rsr/views/my_rsr.py b/akvo/rsr/views/my_rsr.py
--- a/akvo/rsr/views/my_rsr.py
+++ b/akvo/rsr/views/my_rsr.py
@@ -545,7 +545,7 @@ def my_results(request, project_id, template='myrsr/my_results.html'):
     me_managers = project.publishing_orgs.employments().approved().\
         filter(group__in=[admins_group, me_managers_group])
     # Can we unlock and approve?
-    user_is_me_manager = user.is_superuser or user.is_admin or user.me_manager_for_project(project)
+    user_is_me_manager = user.has_perm('rsr.do_me_manager_actions')
     show_narrative_reports = project.partners.filter(
         id__in=settings.NARRATIVE_REPORTS_BETA_ORGS
     ).exists()


Test patch:
Repository: akvo/akvo-rsr

Issue:
Org admin should be able to perform M&E manager actions in Results UI
Org admins should also be included when checking if a user is capable of performing 'M&E Manager actions'


Discussion:

Resolving patch:
diff --git a/akvo/rsr/models/__init__.py b/akvo/rsr/models/__init__.py
--- a/akvo/rsr/models/__init__.py
+++ b/akvo/rsr/models/__init__.py
@@ -212,6 +212,7 @@
 rules.add_perm('rsr.add_indicatorperiod', is_rsr_admin | is_org_admin | is_org_project_editor)
 rules.add_perm('rsr.change_indicatorperiod', is_rsr_admin | is_org_admin | is_org_project_editor)
 rules.add_perm('rsr.delete_indicatorperiod', is_rsr_admin | is_org_admin | is_org_project_editor)
+rules.add_perm('rsr.do_me_manager_actions', is_rsr_admin | is_org_admin | is_org_me_manager)
 
 rules.add_perm('rsr.view_indicatorperioddata', is_rsr_admin | is_org_admin | is_org_me_manager)
 rules.add_perm('rsr.add_indicatorperioddata', is_rsr_admin | is_org_admin | is_org_project_editor)
diff --git a/akvo/rsr/models/user.py b/akvo/rsr/models/user.py
--- a/akvo/rsr/models/user.py
+++ b/akvo/rsr/models/user.py
@@ -379,7 +379,7 @@ def approved_employments(self, group_names=None):
         """
         employments = self.employers.all().exclude(is_approved=False)
         if group_names is not None:
-            employments.filter(group__name__in=group_names)
+            employments = employments.filter(group__name__in=group_names)
         return employments.select_related('organisation', 'group', 'user')
 
     def can_create_project(self):
diff --git a/akvo/rsr/views/my_rsr.py b/akvo/rsr/views/my_rsr.py
--- a/akvo/rsr/views/my_rsr.py
+++ b/akvo/rsr/views/my_rsr.py
@@ -545,7 +545,7 @@ def my_results(request, project_id, template='myrsr/my_results.html'):
     me_managers = project.publishing_orgs.employments().approved().\
         filter(group__in=[admins_group, me_managers_group])
     # Can we unlock and approve?
-    user_is_me_manager = user.is_superuser or user.is_admin or user.me_manager_for_project(project)
+    user_is_me_manager = user.has_perm('rsr.do_me_manager_actions')
     show_narrative_reports = project.partners.filter(
         id__in=settings.NARRATIVE_REPORTS_BETA_ORGS
     ).exists()


Test patch:
Repository: akvo/akvo-rsr

Issue:
Pagination not correct on organisation listing page
When searching or filtering on the organisation listing page, the pagination is not in sync with the results. It always shows as if all organisations are in the search result.

Page 1:
![screenshot_304](https://user-images.githubusercontent.com/142613/41106272-016851d0-6a70-11e8-8950-9b6a0cb4c2fd.png)

Page2:
![screenshot_305](https://user-images.githubusercontent.com/142613/41106280-057b5344-6a70-11e8-91a7-b03fd288f95a.png)



Discussion:

Resolving patch:
diff --git a/akvo/rest/views/organisation.py b/akvo/rest/views/organisation.py
--- a/akvo/rest/views/organisation.py
+++ b/akvo/rest/views/organisation.py
@@ -106,7 +106,7 @@ def organisation_directory(request):
 
     # Get related objects of page at once
     response = {
-        'project_count': all_organisations.count(),
+        'project_count': organisations_text_filtered.count(),
         'projects': OrganisationDirectorySerializer(display_organisations, many=True).data,
         'location': locations,
     }


Test patch: