From 62b6ba06c0e1bdc7a1d964023b2866781ce01b80 Mon Sep 17 00:00:00 2001 From: Eli Chadwick Date: Wed, 20 Sep 2023 14:16:46 +0100 Subject: [PATCH 1/4] Add CLDT to OrganizationManager --- amy/workshops/models.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/amy/workshops/models.py b/amy/workshops/models.py index 0dbe9d0f7..d52d17b44 100644 --- a/amy/workshops/models.py +++ b/amy/workshops/models.py @@ -75,7 +75,10 @@ class OrganizationManager(models.Manager): "software-carpentry.org", "datacarpentry.org", "librarycarpentry.org", - "carpentries.org", # Instructor Training organisation + # Instructor Training organisation + "carpentries.org", + # Collaborative Lesson Development Training organisation + "carpentries.org/community-lessons/", ] def administrators(self): From 8742dc6fd174e4a702a048cb22cf022372c32126 Mon Sep 17 00:00:00 2001 From: Eli Chadwick Date: Wed, 20 Sep 2023 14:16:58 +0100 Subject: [PATCH 2/4] add test for administrators --- amy/fiscal/tests/test_organization.py | 30 +++++++++++++++++++++++++++ amy/workshops/tests/base.py | 23 ++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/amy/fiscal/tests/test_organization.py b/amy/fiscal/tests/test_organization.py index 0cead34b2..b1b9cad49 100644 --- a/amy/fiscal/tests/test_organization.py +++ b/amy/fiscal/tests/test_organization.py @@ -117,3 +117,33 @@ def test_symmetrical_affiliations(self): # Assert self.assertIn(self.org_beta, self.org_alpha.affiliated_organizations.all()) self.assertIn(self.org_alpha, self.org_beta.affiliated_organizations.all()) + + def test_manager_administrators(self): + """Ensure the correct organizations are returned as possible administrators.""" + # Arrange - `setUp()` also creates 2 organisations these filters should ignore + self._setUpAdministrators() + expected_domains = [ + "self-organized", + "software-carpentry.org", + "datacarpentry.org", + "librarycarpentry.org", + # Instructor Training organisation + "carpentries.org", + # Collaborative Lesson Development Training organisation + "carpentries.org/community-lessons/", + ] + + # Act + organizations_with_admin_domain = Organization.objects.filter( + domain__in=expected_domains + ) + administrators = Organization.objects.administrators() + + # Assert + # check that all ADMIN_DOMAINS are represented + self.assertSetEqual( + set(expected_domains), set(Organization.objects.ADMIN_DOMAINS) + ) + self.assertEqual(organizations_with_admin_domain.count(), len(expected_domains)) + # check that administrators() returns what we expect + self.assertQuerysetEqual(organizations_with_admin_domain, administrators) diff --git a/amy/workshops/tests/base.py b/amy/workshops/tests/base.py index 6de700f51..efa3afd97 100644 --- a/amy/workshops/tests/base.py +++ b/amy/workshops/tests/base.py @@ -529,6 +529,29 @@ def _setUpCommunityRoles(self) -> None: award=Award.objects.get(person=self.ron, badge=self.instructor_badge), ) + def _setUpAdministrators(self) -> None: + """Adds administrator organizations to the database.""" + Organization.objects.bulk_create( + [ + Organization(domain="self-organized", fullname="Self-Organized"), + Organization( + domain="software-carpentry.org", + fullname="Software Carpentry", + ), + Organization(domain="datacarpentry.org", fullname="Data Carpentry"), + Organization( + domain="librarycarpentry.org", + fullname="Library Carpentry", + ), + Organization(domain="carpentries.org", fullname="Instructor Training"), + Organization( + domain="carpentries.org/community-lessons/", + fullname="Collaborative Lesson Development Training", + ), + ], + ignore_conflicts=True, + ) + @staticmethod def reconsent(person: Person, term: Term, term_option: TermOption) -> Consent: consent = Consent.objects.get( From 62c0ab70700dfa8fecda65f9527cc302f18c9979 Mon Sep 17 00:00:00 2001 From: Eli Chadwick Date: Wed, 20 Sep 2023 14:25:36 +0100 Subject: [PATCH 3/4] update email checks and user docs with CLDT --- amy/autoemails/actions.py | 5 +++++ docs/users_guide/admin_index.md | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/amy/autoemails/actions.py b/amy/autoemails/actions.py index 7c724b0c0..5c5646d3a 100644 --- a/amy/autoemails/actions.py +++ b/amy/autoemails/actions.py @@ -277,6 +277,8 @@ def check(task: Task): # type: ignore and task.event.administrator and task.event.administrator.domain != "self-organized" and task.event.administrator.domain != "carpentries.org" + # 2023-09-20: also exclude CLDT + and task.event.administrator.domain != "carpentries.org/community-lessons/" ) def get_additional_context(self, objects, *args, **kwargs): @@ -357,6 +359,7 @@ def check(task: Task): # type: ignore and task.event.administrator and task.event.administrator.domain != "self-organized" and task.event.administrator.domain != "carpentries.org" + and task.event.administrator.domain != "carpentries.org/community-lessons/" ) def get_additional_context(self, objects, *args, **kwargs): @@ -488,6 +491,8 @@ def check(event: Event): # type: ignore # Instructor Training and event.administrator and event.administrator.domain != "carpentries.org" + # 2023-09-20: also exclude CLDT + and event.administrator.domain != "carpentries.org/community-lessons/" ) def get_additional_context(self, objects, *args, **kwargs): diff --git a/docs/users_guide/admin_index.md b/docs/users_guide/admin_index.md index 63f93f480..6773a2eb5 100644 --- a/docs/users_guide/admin_index.md +++ b/docs/users_guide/admin_index.md @@ -171,7 +171,7 @@ Go to the [New Event](https://amy.carpentries.org/workshops/events/add/) page by * **Membership** Select the Membership this event should be applied to, by membership term and membership dates. -* **Administrator** Select the administrator from the drop down menu. This will always be `Data Carpentry`, `Library Carpentry`, `Software Carpentry`, `Instructor Training`, or `Self-Organised`. +* **Administrator** Select the administrator from the drop down menu. This will always be `Data Carpentry`, `Library Carpentry`, `Software Carpentry`, `Instructor Training`, `Collaborative Lesson Development Training` or `Self-Organised`. * **Is this workshop public** If the workshop Host consents, choose "Public." This will list the workshop on the websites for The Carpentries, the associated lesson programs, and The Carpentries data feeds. If "Private" it will not be listed publicly anywhere. @@ -608,7 +608,7 @@ Clicking "Events" on the top menu bar will take you to a list of *all* recorded * **Assigned to**: The admin user the event is assigned to * **Tags**: Any tags applied to that event * **Host**: The organisation hosting the event -* **Administrator** The event administrator (A lesson program for centrally organised workshops, self organised, or Instructor Training) +* **Administrator** The event administrator (A lesson program for centrally organised workshops, self organised, Instructor Training, or Collaborative Lesson Development Training) * **Completed** Whether the "completed" box has been checked, indicating all necessary work for that event is complete * **Country** Country from the event's location * **Continent** Continent based on the country From 96190d3001b48db635dd181cdee1a04f6f6027fb Mon Sep 17 00:00:00 2001 From: Eli Chadwick Date: Wed, 20 Sep 2023 14:26:13 +0100 Subject: [PATCH 4/4] include CLDT in database docs --- docs/amy_database_structure.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/amy_database_structure.md b/docs/amy_database_structure.md index 8c954c97e..db570ee8f 100644 --- a/docs/amy_database_structure.md +++ b/docs/amy_database_structure.md @@ -25,7 +25,7 @@ The primary tables used in AMY (that will appear in most queries) are those that * `assigned_to_id` The id of the Regional Coordinator or other Carpentries Core Team member assigned to this event. This is linked to the `workshops_person` table. * `language_id` The integer id of the language used at the workshop. This is not typically recorded. This is linked to the `workshops_language` table * `open_TTT_applications` Used only for instructor training events -* `adminstrator_id` An integer representing the event organizer. This is linked to the `workshops_organization` table. Historically any organization could be listed as an administrator. Recent updates to AMY limit this to Data Carpentry, Library Carpentry, Software Carpentry, The Carpentries, or self-organized. This enforcement is at the AMY app level, not at the database level. +* `adminstrator_id` An integer representing the event organizer. This is linked to the `workshops_organization` table. Historically any organization could be listed as an administrator. Recent updates to AMY limit this to Data Carpentry, Library Carpentry, Software Carpentry, Instructor Training, Collaborative Lesson Development Training, or self-organized. This enforcement is at the AMY app level, not at the database level. * `reg_key` Eventbrite registration key * `instructors_pre` Link to both pre- and post-workshop survey results. @@ -293,4 +293,4 @@ When training request consents are archived, a new unset consent is created by A * `training_request_id` id of the training request this consent option belongs to. This is linked to the `workshops_trainingrequest` table. * `term_id` id of the term this consent applies to. This is linked to the `consents_term` table. There is a check on the Consent model to ensure the given TermOption belongs to the Term. * `term_option_id` id of the term option chosen in this consent. This is linked to the `consents_termoption` table. When this field is null, the consent has not been set by the user. -* `archived_at` a timestamp of when the consent was archived or `NULL` if it wasn't. \ No newline at end of file +* `archived_at` a timestamp of when the consent was archived or `NULL` if it wasn't.