Compare commits

...

38 Commits

Author SHA1 Message Date
95bb467d76 add activity block working 2022-07-09 14:52:45 +01:00
ccbac9473b broke something 2022-07-07 17:20:10 +01:00
07683cd1b8 Add case block is working 2022-07-07 12:54:42 +01:00
2b4b9696db Added block for adding cases to actors 2022-07-07 12:50:02 +01:00
03c826087a Added cases by provider view 2022-07-07 11:39:37 +01:00
c47e4b7b22 Exported current demo config 2022-07-07 11:32:02 +01:00
801c69fa06 added redirect at login 2022-07-05 13:58:10 +01:00
de3a79209b Added cases-by-provider view 2022-07-05 13:30:56 +01:00
7ea66d37a7 Capitalised menu link 2022-07-05 11:55:08 +01:00
cd8974fdb9 changed email fields on org and actor to email type 2022-06-20 14:11:07 +01:00
5e0bde90a0 Deleted old website field 2022-06-20 13:55:21 +01:00
bca978f6f0 Added new website field (org_website) - link field 2022-06-20 13:31:21 +01:00
49bf43e5b4 Added function to cases for getting case provider ids 2022-06-14 13:59:51 +01:00
2c65aff7e1 added method to case to get case provisions 2022-06-07 14:26:51 +01:00
44b9680e0c fixed type error in test for timebasefieldupdater 2022-06-07 13:59:18 +01:00
b70697995a Started adding function to case, to get case providers 2022-06-07 13:54:19 +01:00
ffb56ab09f fixed breadcrumbs so they work for ciac 2022-06-07 13:07:18 +01:00
2f07a2b9aa Added breadcrumb stuff 2022-06-07 12:43:07 +01:00
20f2312245 fixed type error in timebasedfieldupdater 2022-06-07 12:39:22 +01:00
6857bb8d4c Merge branch 'master' of ssh://git.autonomic.zone:2222/autonomic-cooperative/opencase 2022-06-05 17:15:53 +01:00
f48dae3371 Merge branch 'master' of ssh://git.autonomic.zone:2222/autonomic-cooperative/opencase 2022-06-05 16:04:49 +01:00
183537db39 pluraliser ignores selected words e,g, "staff" 2022-06-05 15:49:27 +01:00
fb9737ca04 added extra conditions param to getCountOfCaseProvisions 2022-06-05 14:54:27 +01:00
737104d7bd Merge branch 'master' of ssh://git.autonomic.zone:2222/autonomic-cooperative/opencase 2022-06-05 13:48:15 +01:00
66fa591566 removed utils from timebasedfieldupdater 2022-06-05 13:47:21 +01:00
c318c451dc refactored tests, added EntityTrait 2022-06-05 13:15:33 +01:00
d81e1b3711 Added test for OCActor::getCountOfCaseProvisions 2022-06-05 12:25:28 +01:00
eb9335b250 Revert "commit project after oc case fee bug"
This reverts commit 809dbfc837.
2022-06-03 12:02:45 +02:00
809dbfc837 commit project after oc case fee bug
:wq
2022-06-03 11:53:40 +02:00
156434fecc Merge branch 'master' of ssh://git.autonomic.zone:2222/autonomic-cooperative/opencase 2022-06-03 11:51:45 +02:00
57795b6393 added defauilt value to OCCaseFee 2022-06-03 11:51:37 +02:00
457b4ad694 Merge branch 'revisionerrors' of ssh://git.autonomic.zone:2222/autonomic-cooperative/opencase into revisionerrors 2022-06-03 11:44:32 +02:00
780f144b52 fixed case revisions 2022-06-03 11:44:26 +02:00
33aec90a78 fixed revision reverting error for activities 2022-06-03 10:41:39 +01:00
f9654bcd78 fixed actor and added test for it 2022-05-27 12:09:45 +02:00
4852de71c7 Merge branch 'master' into revisionerrors 2022-05-27 10:25:36 +01:00
c29a480401 Added test for organisation revision 2022-05-27 09:34:37 +01:00
56bc7b83dd added tests for COrganisationRevisionRevertForm 2022-05-24 12:31:03 +01:00
36 changed files with 1139 additions and 141 deletions

View File

@ -1,30 +0,0 @@
uuid: 14120f1a-9009-4ed1-858a-875d748f93fe
langcode: en
status: true
dependencies:
config:
- views.view.activities
module:
- route_condition
- views
theme:
- bartik
id: views_block__activities_block_1
theme: bartik
region: content
weight: 0
provider: null
plugin: 'views_block:activities-block_1'
settings:
id: 'views_block:activities-block_1'
label: ''
label_display: visible
provider: views
context_mapping: { }
views_label: ''
items_per_page: none
visibility:
route:
id: route
negate: false
routes: entity.oc_actor.canonical

View File

@ -18,10 +18,12 @@ dependencies:
- field.field.oc_actor.client.field_nationalities
- field.field.oc_actor.client.field_referred_by
- field.field.oc_actor.client.field_sex
- field.field.oc_actor.client.field_status
- opencase_entities.oc_actor_type.client
module:
- datetime
- file
- hide_revision_field
_core:
default_config_hash: 90BCsdjSFMMiSp2Da3WhMM2sOUliF433LfErYxVCrgk
id: oc_actor.client.default
@ -140,6 +142,16 @@ content:
size: 60
placeholder: ''
third_party_settings: { }
field_status:
type: entity_reference_autocomplete
weight: 81
region: content
settings:
match_operator: CONTAINS
match_limit: 10
size: 60
placeholder: ''
third_party_settings: { }
first_name:
type: string_textfield
weight: 0

View File

@ -18,6 +18,7 @@ dependencies:
- field.field.oc_actor.client.field_nationalities
- field.field.oc_actor.client.field_referred_by
- field.field.oc_actor.client.field_sex
- field.field.oc_actor.client.field_status
- opencase_entities.oc_actor_type.client
module:
- datetime
@ -154,6 +155,14 @@ content:
third_party_settings: { }
weight: 16
region: content
field_status:
type: entity_reference_label
label: above
settings:
link: true
third_party_settings: { }
weight: 20
region: content
name:
type: string
label: above
@ -200,4 +209,5 @@ hidden:
middle_names: true
search_api_excerpt: true
status: true
total_cases: true
user_id: true

View File

@ -0,0 +1,44 @@
uuid: 2df09597-78e1-4410-82a4-a49dd00349c2
langcode: en
status: true
dependencies:
config:
- user.role.authenticated
module:
- datetime
- opencase_entities
- user
id: oc_actor.client.activities
label: Activities
display_label: true
name: activities
description: ''
base_entity_type_id: oc_actor
base_bundle_type_id: client
field_type_id: views
field_type_config:
view_name: activities
display: block_1
arguments: ''
field_type_condition:
'entity_bundle:oc_actor':
id: 'entity_bundle:oc_actor'
negate: false
context_mapping:
oc_actor: entity_extra_field.target_entity
bundles: { }
route:
id: route
negate: false
routes: ''
request_path:
id: request_path
negate: false
pages: ''
current_theme:
id: current_theme
theme: ''
negate: 0
field_conditions_all_pass: false
display:
type: view

View File

@ -0,0 +1,44 @@
uuid: c5f2c484-212c-4b18-ad10-60cbca03029f
langcode: en
status: true
dependencies:
config:
- system.menu.opencase
- user.role.authenticated
module:
- opencase_cases
- user
id: oc_actor.client.cases
label: Cases
display_label: true
name: cases
description: ''
base_entity_type_id: oc_actor
base_bundle_type_id: client
field_type_id: views
field_type_config:
view_name: cases
display: block_1
arguments: ''
field_type_condition:
'entity_bundle:oc_actor':
id: 'entity_bundle:oc_actor'
negate: false
context_mapping:
oc_actor: entity_extra_field.target_entity
bundles: { }
route:
id: route
negate: false
routes: ''
request_path:
id: request_path
negate: false
pages: ''
current_theme:
id: current_theme
theme: ''
negate: 0
field_conditions_all_pass: false
display:
type: view

View File

@ -0,0 +1,21 @@
uuid: 00fcbe97-883d-496c-b22e-fa9bce157a1d
langcode: en
status: true
dependencies:
config:
- field.storage.oc_actor.field_status
- opencase_entities.oc_actor_type.client
id: oc_actor.client.field_status
field_name: field_status
entity_type: oc_actor
bundle: client
label: Status
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:taxonomy_term'
handler_settings: { }
field_type: entity_reference

View File

@ -0,0 +1,20 @@
uuid: cde29136-624d-46a0-8199-820f26cd23fd
langcode: en
status: true
dependencies:
module:
- opencase_entities
- taxonomy
id: oc_actor.field_status
field_name: field_status
entity_type: oc_actor
type: entity_reference
settings:
target_type: taxonomy_term
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@ -0,0 +1,8 @@
uuid: ba139c72-00f4-44d1-be2d-f8ada5aef0c1
langcode: en
status: true
dependencies: { }
name: 'Client statuses'
vid: client_statuses
description: ''
weight: 0

View File

@ -0,0 +1,257 @@
uuid: 24db3b38-2204-47be-8347-20c277b05d2a
langcode: en
status: true
dependencies:
config:
- user.role.authenticated
module:
- opencase_cases
- opencase_entities
- user
id: cases_by_provider
label: 'Cases by provider'
module: views
description: ''
tag: ''
base_table: oc_case_provision_field_data
base_field: id
display:
default:
id: default
display_title: Default
display_plugin: default
position: 0
display_options:
title: 'Cases by provider'
fields:
name_1:
id: name_1
table: oc_case_field_data
field: name
relationship: oc_case
group_type: group
admin_label: ''
entity_type: oc_case
entity_field: name
plugin_id: field
label: Title
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
click_sort_column: value
type: string
settings:
link_to_entity: true
group_column: value
group_columns: { }
group_rows: true
delta_limit: 0
delta_offset: 0
delta_reversed: false
delta_first_last: false
multi_type: separator
separator: ', '
field_api_classes: false
pager:
type: mini
options:
offset: 0
items_per_page: 10
total_pages: null
id: 0
tags:
next:
previous:
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
exposed_form:
type: basic
options:
submit_button: Apply
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
access:
type: role
options:
role:
authenticated: authenticated
cache:
type: tag
options: { }
empty: { }
sorts: { }
arguments:
uid:
id: uid
table: users_field_data
field: uid
relationship: reverse__user__field_linked_opencase_actor
group_type: group
admin_label: ''
entity_type: user
entity_field: uid
plugin_id: user_uid
default_action: default
exception:
value: all
title_enable: false
title: All
title_enable: false
title: ''
default_argument_type: current_user
default_argument_options: { }
default_argument_skip_url: false
summary_options:
base_path: ''
count: true
override: false
items_per_page: 25
summary:
sort_order: asc
number_of_records: 0
format: default_summary
specify_validation: false
validate:
type: none
fail: 'not found'
validate_options: { }
break_phrase: false
not: false
filters:
status:
id: status
table: oc_case_provision_field_data
field: status
entity_type: oc_case_provision
entity_field: status
plugin_id: boolean
value: '1'
group: 1
expose:
operator: ''
operator_limit_selection: false
operator_list: { }
style:
type: table
row:
type: fields
query:
type: views_query
options:
query_comment: ''
disable_sql_rewrite: false
distinct: false
replica: false
query_tags: { }
relationships:
oc_case:
id: oc_case
table: oc_case_provision_field_data
field: oc_case
relationship: none
group_type: group
admin_label: Case
entity_type: oc_case_provision
entity_field: oc_case
plugin_id: standard
required: true
oc_provider:
id: oc_provider
table: oc_case_provision_field_data
field: oc_provider
relationship: none
group_type: group
admin_label: Person
entity_type: oc_case_provision
entity_field: oc_provider
plugin_id: standard
required: true
reverse__user__field_linked_opencase_actor:
id: reverse__user__field_linked_opencase_actor
table: oc_actor_field_data
field: reverse__user__field_linked_opencase_actor
relationship: oc_provider
group_type: group
admin_label: User
entity_type: oc_actor
plugin_id: entity_reverse
required: true
header: { }
footer: { }
display_extenders: { }
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- user
- user.roles
tags: { }
page_1:
id: page_1
display_title: Page
display_plugin: page
position: 1
display_options:
display_extenders: { }
path: cases-by-provider
cache_metadata:
max-age: -1
contexts:
- 'languages:language_content'
- 'languages:language_interface'
- url
- url.query_args
- user
- user.roles
tags: { }

View File

@ -2,6 +2,7 @@
namespace Drupal\opencase_cases\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\RevisionableContentEntityBase;
@ -83,6 +84,10 @@ class OCCase extends RevisionableContentEntityBase implements OCCaseInterface
/**
* {@inheritdoc}
*/
public static function loadFromUrlQueryParameter(string $param) {
return self::load(\Drupal::request()->query->get($param));
}
public static function preCreate(EntityStorageInterface $storage_controller, array &$values)
{
parent::preCreate($storage_controller, $values);
@ -91,6 +96,26 @@ class OCCase extends RevisionableContentEntityBase implements OCCaseInterface
];
}
public function getCaseProviderIds(int $role_id = null): array {
$case_provision_ids = $this->getCaseProvisionIds();
$provider_ids = [];
foreach($case_provision_ids as $id) {
$provision = \Drupal::entityTypeManager()->getStorage('oc_case_provision')->load($id);
if ($provision instanceOf OCCaseProvision) {
if (is_null($role_id) || $role_id == $provision->get('oc_case_provider_role')->target_id) {
$provider_ids[] = $provision->get('oc_provider')->target_id;
}
}
}
return $provider_ids;
}
private function getCaseProvisionIds(): array {
$query = \Drupal::entityTypeManager()->getStorage('oc_case_provision')->getQuery();
$query->condition('oc_case.target_id', $this->id());
return $query->execute();
}
public function deleteCaseProvisions(): void {
$this->deleteChildren('oc_case_provision');
}
@ -98,8 +123,7 @@ class OCCase extends RevisionableContentEntityBase implements OCCaseInterface
$this->deleteChildren('oc_activity');
}
public function deleteChildren($child_entity_type):void {
private function deleteChildren($child_entity_type):void {
$query = \Drupal::entityQuery($child_entity_type)
->condition('oc_case.target_id', $this->id());
$ids = $query->execute();
@ -116,6 +140,16 @@ class OCCase extends RevisionableContentEntityBase implements OCCaseInterface
else return [];
}
public function getTargetEntity(): ContentEntityBase {
if (!$this->oc_target->isEmpty()) {
return $this->oc_target->entity;
} elseif ($this->hasField('client') && !$this->client->isEmpty()) {
return $this->client->entity;
} else {
throw new \Exception('No target found on case');
}
}
/**
* {@inheritdoc}
*/

View File

@ -230,7 +230,8 @@ class OCCaseFee extends EditorialContentEntityBase implements OCCaseFeeInterface
->setLabel(t('Visible'))
->setDescription(t('A boolean indicating whether the Case Fee is published.'))
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
->setDisplayConfigurable('view', TRUE)
->setDefaultValue(TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
@ -268,7 +269,7 @@ class OCCaseFee extends EditorialContentEntityBase implements OCCaseFeeInterface
->setDisplayConfigurable("view", true)
->setDisplayConfigurable("form", true)
->setRequired(FALSE);
$fields['description'] = BaseFieldDefinition::create('string_long')
->setRevisionable(TRUE)
->setLabel(t('Description'))

View File

@ -36,7 +36,7 @@ class OCCaseForm extends ContentEntityForm {
/**
* {@inheritdoc}
*/
public function save(array $form, FormStateInterface $form_state) {
public function save(array $form, FormStateInterface $form_state): void {
$entity = $this->entity;
$entity->setNewRevision();
$entity->setRevisionCreationTime(REQUEST_TIME);
@ -57,7 +57,7 @@ class OCCaseForm extends ContentEntityForm {
]));
}
// If you have unpublished the entity and you can't see unpublished entities, redirect to a more informative message than just "Access Denied".
if (!$form_state->getValue('status')['value'] && !\Drupal::currentUser()->hasPermission('view unpublished case entities')) {
if (!$this->isPublished($form_state) && !\Drupal::currentUser()->hasPermission('view unpublished case entities')) {
\Drupal::messenger()->addMessage($this->t('The record for "%label" is now unpublished & hidden from you.', [
'%label' => $entity->label(),
]));
@ -67,4 +67,12 @@ class OCCaseForm extends ContentEntityForm {
}
}
private function isPublished(FormStateInterface $form_state): bool {
if (is_null($form_state->getValue('status'))) {
return false; // some entities have nothing set for the status in which case we want to treat them as published by default.
// TODO why don't they??
}
return $form_state->getValue('status')['value'];
}
}

View File

@ -56,10 +56,10 @@ class OCCaseRevisionRevertForm extends ConfirmFormBase {
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager')->getStorage('oc_case'),
$container->get('date.formatter')
);
return new static($container
->get('entity_type.manager')
->getStorage('oc_case'), $container
->get('date.formatter'));
}
/**

View File

@ -1,40 +0,0 @@
<?php
namespace Drupal\opencase_cases\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a Block for adding a case for the current client
*
* @Block(
* id = "add_case",
* admin_label = @Translation("Add Case"),
* category = @Translation("Opencase"),
* )
*/
class AddCase extends BlockBase {
/**
* {@inheritdoc}
*/
public function build():array {
$target_id = \Drupal::routeMatch()->getParameter('oc_actor')->id();
$case_types = \Drupal::service('entity_type.bundle.info')->getBundleInfo('oc_case');
$markup = "<ul>";
foreach($case_types as $id => $info) {
$label = $info['label'];
$markup .= "<li><a href='/opencase/oc_case/add/$id?target_id=$target_id'>$label</a></li>";
}
$markup .= "</ul>";
return array(
'#markup' => $markup
);
}
public function getCacheMaxAge():int {
return 0;
}
}

View File

@ -4,6 +4,30 @@
use \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchemaConverter;
use \Drupal\Core\Field\BaseFieldDefinition;
function opencase_entities_update_90004() {
$update_manager = \Drupal::entityDefinitionUpdateManager();
$definition = $update_manager->getFieldStorageDefinition('website', 'oc_organisation');
$update_manager->uninstallFieldStorageDefinition($definition);
}
function opencase_entities_update_90003() {
$field_storage_definition = BaseFieldDefinition::create('link')
->setLabel(t('Website'))
->setRevisionable(TRUE)
->setSettings([
'max_length' => 50,
'text_processing' => 0,
])
->setDefaultValue('')
->setDisplayConfigurable('form', true)
->setDisplayConfigurable('view', true)
->setRequired(FALSE);
\Drupal::entityDefinitionUpdateManager()
->installFieldStorageDefinition('org_website', 'oc_organisation', 'opencase_entities', $field_storage_definition);
}
function opencase_entities_update_90002() {
$field_storage_definition = BaseFieldDefinition::create('entity_reference')

View File

@ -211,6 +211,9 @@ class OCActor extends RevisionableContentEntityBase implements OCActorInterface
public function getCountOfCaseProvisions(array $conditionsToApplyToCaseProvisionQuery = []): int {
$query = \Drupal::entityQuery('oc_case_provision');
$query->condition('oc_provider', $this->id());
foreach($conditionsToApplyToCaseProvisionQuery as $condition) {
$query->condition($condition[0], $condition[1], $condition[2] ?? '=');
}
return count($query->execute());
}
@ -291,7 +294,7 @@ class OCActor extends RevisionableContentEntityBase implements OCActorInterface
->setRequired(TRUE);
// Contact details.
$fields['email'] = BaseFieldDefinition::create('string')
$fields['email'] = BaseFieldDefinition::create('email')
->setLabel(t('Email Address'))
->setRevisionable(TRUE)
->setSettings(array(

View File

@ -211,17 +211,20 @@ class OCOrganisation extends EditorialContentEntityBase implements OCOrganisatio
'max_length' => 255,
'text_processing' => 0,
));
$fields['website'] = BaseFieldDefinition::create('string')
$fields['org_website'] = BaseFieldDefinition::create('link')
->setLabel(t('Website'))
->setRevisionable(TRUE)
->setSettings([
'max_length' => 50,
'text_processing' => 0,
'title' => 0,
'link_type' => 16
])
->setDefaultValue('')
->setDisplayConfigurable('form', true)
->setDisplayConfigurable('view', true)
->setRequired(FALSE);
$fields['contact_name'] = BaseFieldDefinition::create('string')
->setLabel(t('Contact Name'))
->setDescription(t('Name of the main contact for this organisation.'))
@ -247,14 +250,10 @@ class OCOrganisation extends EditorialContentEntityBase implements OCOrganisatio
->setDisplayConfigurable('form', true)
->setDisplayConfigurable('view', true)
->setRequired(FALSE);
$fields['email'] = BaseFieldDefinition::create('string')
$fields['email'] = BaseFieldDefinition::create('email')
->setLabel(t('Email Address'))
->setRevisionable(TRUE)
->setSettings(array(
'default_value' => '',
'max_length' => 100,
'text_processing' => 0,
))
->setDisplayConfigurable('form', true)
->setDisplayConfigurable('view', true);
@ -302,7 +301,7 @@ class OCOrganisation extends EditorialContentEntityBase implements OCOrganisatio
->setDisplayConfigurable('view', true)
->setRequired(FALSE);
$fields['billing_email'] = BaseFieldDefinition::create('string')
$fields['billing_email'] = BaseFieldDefinition::create('email')
->setLabel(t('Billing Email Address'))
->setRevisionable(TRUE)
->setSettings(array(

View File

@ -57,7 +57,7 @@ class OCActivityRevisionRevertForm extends ConfirmFormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager')->getStorage('oc_activity'),
$container->get('entity_type.manager')->getStorage('oc_activity'),
$container->get('date.formatter')
);
}

View File

@ -56,10 +56,10 @@ class OCActorRevisionRevertForm extends ConfirmFormBase {
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager')->getStorage('oc_actor'),
$container->get('date.formatter')
);
return new static($container
->get('entity_type.manager')
->getStorage('oc_actor'), $container
->get('date.formatter'));
}
/**

View File

@ -41,14 +41,14 @@ class OCOrganisationRevisionRevertForm extends ConfirmFormBase {
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->oCOrganisationStorage = $container->get('entity_type.manager')->getStorage('oc_organisation');
$instance->OCOrganisationStorage = $container->get('entity_type.manager')->getStorage('oc_organisation');
$instance->dateFormatter = $container->get('date.formatter');
return $instance;
}
/**
* {@inheritdoc}
*/
*/
public function getFormId() {
return 'oc_organisation_revision_revert_confirm';
}

View File

@ -56,7 +56,7 @@ opencase.manage_taxonomy_links:
menu_name: opencase
parent: opencase.opencase_admin_menu
opencase.manage_user_logins:
title: 'Manage user logins'
title: 'Manage User Logins'
description: 'Manage who can access the system'
menu_name: opencase
parent: opencase.opencase_admin_menu

View File

@ -9,6 +9,25 @@ use Drupal\Core\Access\AccessResult;
use Drupal\opencase_cases\Entity\OCCase;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\opencase_cases\Entity\OCCaseProvision;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
/**
* Implements hook_form_FORM_ID_alter().
*/
function opencase_form_user_login_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$form['#submit'][] = 'opencase_user_login_form_submit';
}
/**
* If the user does not have permissions to see all cases, then when the login they are
* redirected to a view of just their own cases.
*/
function opencase_user_login_form_submit($form, FormStateInterface $form_state) {
if (!\Drupal::currentUser()->hasPermission('view published case entities')) {
$form_state->setRedirectUrl(Url::fromRoute('view.cases_by_provider.page_1'));
}
}
/**
* Implements hook_element_info_alter().
@ -158,17 +177,42 @@ function opencase_entity_field_access($operation, \Drupal\Core\Field\FieldDefini
}
/*
Implementation of hook_relevant_activity_type_ids which is a custom hook invoked in the AddActivity block.
Custom hook
*/
function opencase_relevant_activity_type_ids($actorTypeID) {
switch ($actorTypeID) {
case 'volunteer':
return ['email', 'phone_call', 'supervision'];
case 'client':
return ['email', 'lete', 'phone_call', 'case_note', 'destitution_funds_provided', 'research', 'application'];
case 'staff_member':
return ['application', 'interview'];
function opencase_relevant_case_type_ids(string $bundle):array {
switch ($bundle) {
case 'client':
return ['accommodation', 'asylum_support', 'employability', 'health', 'immigration', 'welfare_rights'];
case 'volunteer':
return ['volunteer_engagement'];
}
return [];
}
/*
Custom hook
*/
function opencase_relevant_activity_type_ids(string $entityType, string $bundle):array {
if ($entityType == 'oc_actor') {
switch ($bundle) {
case 'volunteer':
return ['email', 'phone_call', 'supervision', 'application', 'interview'];
case 'client':
return ['email', 'lete', 'phone_call', 'case_note', 'destitution_funds_provided', 'research', 'application'];
case 'staff_member':
return ['application', 'interview'];
}
}
if ($entityType == 'oc_case') {
switch ($bundle) {
case 'volunteer_engagement':
return ['email', 'phone_call', 'supervision', 'application', 'interview'];
default:
return ['email', 'lete', 'phone_call', 'case_note', 'destitution_funds_provided', 'research', 'application'];
}
}
return [];
}
/**

8
opencase.services.yml Normal file
View File

@ -0,0 +1,8 @@
services:
opencase.breadcrumb:
# The namespace + classname from your BreadcrumbBuilderInterface class
class: Drupal\opencase\Breadcrumb\BreadcrumbBuilder
# Priority determines the order in which Breadcrumb services run.
tags:
- { name: breadcrumb_builder, priority: 100 }

View File

@ -0,0 +1,37 @@
Name,"Accreditation date","Client type","Client subtype","Client Status","Client substatus",Tags,"Umbrella client","Type of umbrella client",Address
testqweqew,"03 Apr 2022","Nightlife Organisation",,Accredited,"Recently Accredited",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,test,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead","Community Project",,,
test,,,,Lead,"New lead",,test,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,test,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
test,,,,Lead,"New lead",,,,
testd,,,,Lead,"New lead",,,,
Friday,"16 May 2022",,,Accredited,"Recently Accredited","Open Access Session",test,,
1 Name Accreditation date Client type Client subtype Client Status Client substatus Tags Umbrella client Type of umbrella client Address
2 testqweqew 03 Apr 2022 Nightlife Organisation Accredited Recently Accredited
3 test Lead New lead
4 test Lead New lead
5 test Lead New lead
6 test Lead New lead
7 test Lead New lead
8 test Lead New lead
9 test Lead New lead
10 test Lead New lead
11 test Lead New lead
12 test Lead New lead
13 test Lead New lead test
14 test Lead New lead
15 test Lead New lead
16 test Lead New lead
17 test Lead New lead
18 test Lead New lead
19 test Lead New lead Community Project
20 test Lead New lead test
21 test Lead New lead
22 test Lead New lead
23 test Lead New lead
24 test Lead New lead
25 test Lead New lead
26 test Lead New lead
27 test Lead New lead
28 test Lead New lead
29 test Lead New lead
30 test Lead New lead
31 test Lead New lead
32 test Lead New lead test
33 test Lead New lead
34 test Lead New lead
35 test Lead New lead
36 testd Lead New lead
37 Friday 16 May 2022 Accredited Recently Accredited Open Access Session test

View File

@ -0,0 +1,23 @@
"Date submitted",Training,"Submitted by",view_oc_activity
"12 Sep 2021",,,view
"11 Sep 2021",,,view
"11 Sep 2021",,,view
"11 Sep 2021",,,view
"11 Sep 2021",,,view
"11 Sep 2021",,,view
"11 Sep 2021",,,view
"11 Sep 2021",,,view
"17 Sep 2021",,,view
"17 Sep 2021",,,view
"17 Sep 2021",,,view
"17 Sep 2021",,,view
"17 Sep 2021",,,view
"17 Sep 2021",,,view
"17 Sep 2021",,,view
"17 Sep 2021",,,view
"17 Sep 2021",,,view
"23 Oct 2021",,,view
"23 Oct 2021",,,view
"12 Nov 2021",,,view
"12 Nov 2021",,,view
"16 Nov 2021",,,view
1 Date submitted Training Submitted by view_oc_activity
2 12 Sep 2021 view
3 11 Sep 2021 view
4 11 Sep 2021 view
5 11 Sep 2021 view
6 11 Sep 2021 view
7 11 Sep 2021 view
8 11 Sep 2021 view
9 11 Sep 2021 view
10 17 Sep 2021 view
11 17 Sep 2021 view
12 17 Sep 2021 view
13 17 Sep 2021 view
14 17 Sep 2021 view
15 17 Sep 2021 view
16 17 Sep 2021 view
17 17 Sep 2021 view
18 17 Sep 2021 view
19 23 Oct 2021 view
20 23 Oct 2021 view
21 12 Nov 2021 view
22 12 Nov 2021 view
23 16 Nov 2021 view

View File

@ -0,0 +1,105 @@
<?php declare(strict_types = 1);
namespace Drupal\opencase\Breadcrumb;
use Drupal\Core\Link ;
use Drupal\Core\Breadcrumb\Breadcrumb;
use Drupal\opencase_cases\Entity\OCCase;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\opencase_entities\Entity\OCOrganisation;
use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
class BreadcrumbBuilder implements BreadcrumbBuilderInterface {
private string $title;
private function addTitle($route_match) {
$title = $this->title ?? $this->getPageTitle($route_match);
$this->breadcrumb->addLink(Link::createFromRoute($title, '<none>'));
}
/**
* {@inheritdoc}
*/
public function applies(RouteMatchInterface $route_match) {
return TRUE;
}
private function getPageTitle($route_match) {
$request = \Drupal::request();
return \Drupal::service('title_resolver')->getTitle($request, $route_match->getRouteObject());
}
private function addLinksForCaseTarget(ContentEntityBase $entity) {
if ($entity instanceof OCOrganisation) {
$this->addLinksForOrganisation($entity);
}
}
private function addLinksForOrganisation(ContentEntityBase $entity) {
$fields = ['field_umbrella_client'];
$this->addLinks($entity, $fields);
}
private function addLinksForCase(OCCase $case) {
$fields = ['client', 'field_project'];
$this->addLinksForCaseTarget($case->getTargetEntity());
$this->addLinks($case, $fields);
}
private function addLinks(ContentEntityBase $entity, array $fields) {
foreach ($fields as $field) {
if ($entity->hasField($field) && !$entity->get($field)->isEmpty()) {
$this->breadcrumb->addLink($entity->$field->entity->toLink());
}
}
}
/**
* {@inheritdoc}
*/
public function build(RouteMatchInterface $route_match) {
$this->breadcrumb = new Breadcrumb();
$this->breadcrumb->addLink(Link::createFromRoute('Home', '<front>'));
$params = $route_match->getParameters();
if ($params->has('oc_activity')) {
$activity = $params->get('oc_activity');
if (!$activity->get('oc_case')->isEmpty()){
$this->addLinksForCase($activity->get('oc_case')->entity);
}
$this->addLinks($activity, ['client', 'oc_case']);
$this->title = $activity->getName() ?? $activity->type->entity->label();
}
elseif ($params->has('oc_organisation')) {
$this->addLinksForOrganisation($params->get('oc_organisation'));
}
elseif ($params->has('oc_case')) {
$this->addLinksForCase($params->get('oc_case'));
}
elseif ($params->has('oc_case_fee')) {
$case_provision = $params->get('oc_case_fee');
$this->addLinksForCase($case_provision->get('oc_case')->entity);
$this->addLinks($case_provision, ['oc_case']);
$this->title = "Fee";
}
elseif ($params->has('oc_case_provision')) {
$case_provision = $params->get('oc_case_provision');
$this->addLinksForCase($case_provision->get('oc_case')->entity);
$this->addLinks($case_provision, ['oc_case']);
$this->title = $case_provision->type->entity->label();
}
$this->addTitle($route_match);
// Don't forget to add cache control by a route.
// Otherwise all pages will have the same breadcrumb.
$this->breadcrumb->addCacheContexts(['route']);
return $this->breadcrumb;
}
}

View File

@ -3,6 +3,8 @@
namespace Drupal\opencase\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\opencase_cases\Entity\OCCase;
use Drupal\opencase_entities\Entity\OCActor;
/**
* Provides a Block with some help text about actor type fields
@ -19,28 +21,57 @@ class AddActivity extends BlockBase {
* {@inheritdoc}
*/
public function build():array {
if ($this->isOnACase()) {
return $this->makeBlockForAddingActivityToCase();
} elseif ($this->isOnAnActor()) {
return $this->makeBlockForAddingActivityToActor();
}
return ['#markup' => 'This block should only be placed on a case or on an actor.'];
}
private function makeBlockForAddingActivityToCase():array {
$case = \Drupal::routeMatch()->getParameter('oc_case');
$case_id = $case->id();
$markup = "<ul>";
$bundles = $this->getActivityBundlesFor('oc_case', $case->bundle());
foreach($bundles as $bundle => $info) {
$label = $info['label'];
$markup .= "<li><a href='/opencase/oc_activity/add/$bundle?case_id=$case_id&destination=/opencase/oc_case/$case_id'>$label</a></li>";
}
$markup .= "</ul>";
return array('#markup' => $markup);
}
private function makeBlockForAddingActivityToActor():array {
$actor = \Drupal::routeMatch()->getParameter('oc_actor');
$target_id = $actor->id();
$actorType = $actor->bundle();
$markup = "<ul>";
$activity_types = $this->getActivityTypesToDisplay($actorType);
foreach($activity_types as $id => $info) {
$bundles = $this->getActivityBundlesFor('oc_actor', $actor->bundle());
foreach($bundles as $bundle => $info) {
$label = $info['label'];
$markup .= "<li><a href='/opencase/oc_activity/add/$id?target_id=$target_id&destination=/opencase/oc_actor/$target_id'>$label</a></li>";
$markup .= "<li><a href='/opencase/oc_activity/add/$bundle?target_id=$target_id&destination=/opencase/oc_actor/$target_id'>$label</a></li>";
}
$markup .= "</ul>";
return array('#markup' => $markup);
}
private function isOnACase():bool {
return \Drupal::routeMatch()->getParameter('oc_case') instanceof OCCase;
}
private function isOnAnActor():bool {
return \Drupal::routeMatch()->getParameter('oc_actor') instanceof OCActor;
}
public function getCacheMaxAge():int {
return 0;
}
private function getActivityTypesToDisplay(string $actorType): array {
private function getActivityBundlesFor(string $entityType, string $bundle): array {
// Client modules will provide a list of what activity types (bundles) are relevant for each actor type.
// Check if they are implemented, and if so display them.
$implemented_activity_types = \Drupal::service('entity_type.bundle.info')->getBundleInfo('oc_activity');
$relevant_activity_type_ids = \Drupal::moduleHandler()->invokeAll('relevant_activity_type_ids', [$actorType]);
$relevant_activity_type_ids = \Drupal::moduleHandler()->invokeAll('relevant_activity_type_ids', [$entityType, $bundle]);
$activity_types_to_display = [];
foreach ($relevant_activity_type_ids as $type_id) {
if (array_key_exists($type_id, $implemented_activity_types)) {

View File

@ -0,0 +1,52 @@
<?php declare(strict_types = 1);
namespace Drupal\opencase\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a Block for adding cases to an actor
*
* @Block(
* id = "add_case",
* admin_label = @Translation("Add Case"),
* category = @Translation("Opencase"),
* )
*/
class AddCase extends BlockBase {
/**
* {@inheritdoc}
*/
public function build():array {
$actor = \Drupal::routeMatch()->getParameter('oc_actor');
$target_id = $actor->id();
$actorType = $actor->bundle();
$markup = "<ul>";
$case_types = $this->getCaseTypesToDisplay($actorType);
foreach($case_types as $id => $info) {
$label = $info['label'];
$markup .= "<li><a href='/opencase/oc_case/add/$id?target_id=$target_id&destination=/opencase/oc_actor/$target_id'>$label</a></li>";
}
$markup .= "</ul>";
return array('#markup' => $markup);
}
public function getCacheMaxAge():int {
return 0;
}
private function getCaseTypesToDisplay(string $actorType): array {
// Client modules will provide a list of what case types (bundles) are relevant for each actor type.
// Check if they are implemented, and if so display them.
$implemented_case_types = \Drupal::service('entity_type.bundle.info')->getBundleInfo('oc_case');
$relevant_case_type_ids = \Drupal::moduleHandler()->invokeAll('relevant_case_type_ids', [$actorType]);
$case_types_to_display = [];
foreach ($relevant_case_type_ids as $type_id) {
if (array_key_exists($type_id, $implemented_case_types)) {
$case_types_to_display[$type_id] = $implemented_case_types[$type_id];
}
}
return $case_types_to_display;
}
}

View File

@ -45,7 +45,7 @@ class AddEventsMenuLink extends DeriverBase implements ContainerDeriverInterface
$eventTypes = $this->entityTypeManager->getStorage('oc_event_type')->loadMultiple();
foreach ($eventTypes as $id => $eventType) {
$links[$id] = [
'title' => $eventType->label(),
'title' => $eventType->label() . " Event",
'route_name' => "entity.oc_event.add_form",
'route_parameters' => ['oc_event_type' => $eventType->id()]
] + $base_plugin_definition;

View File

@ -2,8 +2,14 @@
namespace Drupal\opencase;
class Pluraliser {
const NO_CHANGE = ['Staff'];
public static function pluralise($text) {
return $text . "s";
if (in_array($text, self::NO_CHANGE)) {
return $text;
} else {
return $text . "s";
}
}
}

View File

@ -2,25 +2,21 @@
namespace Drupal\opencase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\opencase\Utils;
final class TimeBasedFieldUpdater {
private EntityTypeManagerInterface $entityTypeManager;
private string $date_field;
private Utils $utils;
private string $entity_type;
private string $date_format;
private string $bundle;
final public function __construct(
EntityTypeManagerInterface $entityTypeManager,
Utils $utils,
string $entity_type, string $bundle, string $date_field, string $date_format = 'Y-m-d'
)
{
$this->entityTypeManager = $entityTypeManager;
$this->utils = $utils;
$this->date_field = $date_field;
$this->date_format = $date_format;
$this->entity_type = $entity_type;
@ -39,7 +35,7 @@ final class TimeBasedFieldUpdater {
$this->updateEntity($id, $new_values);
}
}
private function updateEntity(int $entity_id, array $new_values): void {
private function updateEntity(string $entity_id, array $new_values): void {
$entity = $this->entityTypeManager->getStorage($this->entity_type)->load($entity_id);
foreach($new_values as $new_field=>$new_value) {
$entity->$new_field = $new_value;

View File

@ -0,0 +1,38 @@
<?php
namespace Drupal\Tests\opencase\Unit;
use PHPUnit\Framework\MockObject\MockObject;
use Drupal\Core\DependencyInjection\ContainerBuilder;
trait EntityTrait {
public function getEntityTypeManager() {
return $this->getMockBuilder('\\Drupal\\Core\\Entity\\EntityTypeManager')->disableOriginalConstructor()->getMock();
}
public function getStorage(MockObject $entityTypeManager, string $entityTypeToExpect = ''): MockObject {
$storage = $this->getMockBuilder('\\Drupal\\Core\\Entity\\EntityStorageInterface')->disableOriginalConstructor()->getMock();
$entityTypeManager->method('getStorage')->willReturn($storage);
if ($entityTypeToExpect) {
$entityTypeManager->expects($this->any())->method('getStorage')->with($entityTypeToExpect)->willReturn($storage);
}
return $storage;
}
public function getQuery(MockObject $storage): MockObject {
$query = $this->getMockBuilder('\\Drupal\\Core\\Entity\\Query\\QueryInterface')->getMock();
$storage->method('getQuery')->willReturn($query);
return $query;
}
public function getEntity(): MockObject {
return $this->getMockBuilder('\\Drupal\\Core\\Entity\\EntityBase')->disableOriginalConstructor()->getMock();
}
public function getContainer(array $services): ContainerBuilder {
$container = new ContainerBuilder();
foreach ($services as $key => $mock) {
$container->set($key, $mock);
}
\Drupal::setContainer($container);
return $container;
}
}

View File

@ -0,0 +1,61 @@
<?php declare(strict_types = 1);
namespace Drupal\Tests\opencase\Unit;
use Drupal\Tests\UnitTestCase;
class OCActorTest extends UnitTestCase{
use EntityTrait;
public function setUp(): void {
$this->etm = $this->getEntityTypeManager();
$this->getContainer([
'entity_type.manager' => $this->etm
]);
}
public function testGetCountOfCaseProvisionsWithNoExtraConditions(): void{
$storage = $this->getStorage($this->etm, 'oc_case_provision');
$query = $this->getQuery($storage);
$actor = $this->getMockBuilder('\\Drupal\\opencase_entities\\Entity\\OCActor')->disableOriginalConstructor()
->onlyMethods(['id'])
->getMock();
$actor->expects($this->once())->method('id')->willReturn(5);
$query->expects($this->once())->method('condition')->with('oc_provider', 5);
$query->expects($this->once())->method('execute')->willReturn([1,2,3,4]);
$count = $actor->getCountOfCaseProvisions();
$this->assertTrue($count == 4);
}
public function testGetCountOfCaseProvisionsWithExtraConditions(): void{
$storage = $this->getStorage($this->etm, 'oc_case_provision');
$query = $this->getQuery($storage);
$actor = $this->getMockBuilder('\\Drupal\\opencase_entities\\Entity\\OCActor')->disableOriginalConstructor()
->onlyMethods(['id'])
->getMock();
$actor->expects($this->once())->method('id')->willReturn(5);
$query->expects($this->exactly(2))->method('condition')->withConsecutive(
['oc_provider', 5],
['some_date_field', '2022-01-01', '<']);
$query->expects($this->once())->method('execute')->willReturn([1,2,3,4]);
$count = $actor->getCountOfCaseProvisions([['some_date_field', '2022-01-01', '<']]);
$this->assertTrue($count == 4);
}
public function testGetCountOfCaseProvisionsWithExtraConditionsWithAssumedEqualityOperator(): void{
$storage = $this->getStorage($this->etm, 'oc_case_provision');
$query = $this->getQuery($storage);
$actor = $this->getMockBuilder('\\Drupal\\opencase_entities\\Entity\\OCActor')->disableOriginalConstructor()
->onlyMethods(['id'])
->getMock();
$actor->expects($this->once())->method('id')->willReturn(5);
$query->expects($this->exactly(2))->method('condition')->withConsecutive(
['oc_provider', 5],
['some_date_field', '2022-01-01', '=']);
$query->expects($this->once())->method('execute')->willReturn([1,2,3,4]);
$count = $actor->getCountOfCaseProvisions([['some_date_field', '2022-01-01']]);
$this->assertTrue($count == 4);
}
}

View File

@ -0,0 +1,125 @@
<?php declare(strict_types = 1);
namespace Drupal\Tests\opencase\Unit;
use Drupal\Tests\UnitTestCase;
class OCCaseTest extends UnitTestCase{
use EntityTrait;
private $case;
public function setUp(): void {
$this->etm = $this->getEntityTypeManager();
$this->getContainer([
'entity_type.manager' => $this->etm
]);
$this->case = $this->getMockBuilder('\\Drupal\\opencase_cases\\Entity\\OCCase')->disableOriginalConstructor()
->onlyMethods(['id'])
->getMock();
}
public function testGetCaseProviderIds_SingleCaseProvision(): void{
// It will first get the id of the case provision that references this case
$storage = $this->getStorage($this->etm, 'oc_case_provision');
$query = $this->getQuery($storage);
$this->case->expects($this->once())->method('id')->willReturn(5);
$query->expects($this->once())->method('condition')->with('oc_case.target_id', 5);
$query->expects($this->once())->method('execute')->willReturn([1]);
// Then it will load the provision
$provision = $this->getMockBuilder('\\Drupal\\opencase_cases\\Entity\\OCCaseProvision')->disableOriginalConstructor()->getMock();
$storage->expects($this->once())->method('load')->with(1)->willReturn($provision);
// Then it will get the target id of the provider field from the provision and return it as an array
$providerField = $this->getMockBuilder('\\Drupal\\COre\\Field\\FieldItemListInterface')->disableOriginalConstructor()->getMock();
$providerField->target_id = '45';
$provision->expects($this->once())->method('get')->with('oc_provider')->willReturn($providerField);
$ids = $this->case->getCaseProviderIds();
$this->assertTrue($ids == [45]);
}
public function testGetCaseProviderIds_MultipleCaseProvisions(): void{
// It will first get the id of the case provisions that reference this case
$storage = $this->getStorage($this->etm, 'oc_case_provision');
$query = $this->getQuery($storage);
$this->case->expects($this->once())->method('id')->willReturn(5);
$query->expects($this->once())->method('condition')->with('oc_case.target_id', 5);
$query->expects($this->once())->method('execute')->willReturn([1, 2, 3]);
// Then it will load the provisions
$provision1 = $this->getMockBuilder('\\Drupal\\opencase_cases\\Entity\\OCCaseProvision')->disableOriginalConstructor()->getMock();
$provision2 = $this->getMockBuilder('\\Drupal\\opencase_cases\\Entity\\OCCaseProvision')->disableOriginalConstructor()->getMock();
$provision3 = $this->getMockBuilder('\\Drupal\\opencase_cases\\Entity\\OCCaseProvision')->disableOriginalConstructor()->getMock();
$storage->method('load')->willReturnMap([[1, $provision1], [2, $provision2], [3, $provision3]]);
// Then it will get the target id of the provider field from each provision and return them as an array
$providerField1 = $this->getMockBuilder('\\Drupal\\COre\\Field\\FieldItemListInterface')->disableOriginalConstructor()->getMock();
$providerField1->target_id = '45';
$provision1->expects($this->once())->method('get')->with('oc_provider')->willReturn($providerField1);
$providerField2 = $this->getMockBuilder('\\Drupal\\COre\\Field\\FieldItemListInterface')->disableOriginalConstructor()->getMock();
$providerField2->target_id = '55';
$provision2->expects($this->once())->method('get')->with('oc_provider')->willReturn($providerField2);
$providerField3 = $this->getMockBuilder('\\Drupal\\COre\\Field\\FieldItemListInterface')->disableOriginalConstructor()->getMock();
$providerField3->target_id = '65';
$provision3->expects($this->once())->method('get')->with('oc_provider')->willReturn($providerField3);
$ids = $this->case->getCaseProviderIds();
$this->assertTrue($ids == [45, 55, 65]);
}
public function testGetCaseProviderIds_SingleCaseProvision_RoleSpecifiedAndMatched(): void{
// It will first get the id of the case provision that references this case
$storage = $this->getStorage($this->etm, 'oc_case_provision');
$query = $this->getQuery($storage);
$this->case->expects($this->once())->method('id')->willReturn(5);
$query->expects($this->once())->method('condition')->with('oc_case.target_id', 5);
$query->expects($this->once())->method('execute')->willReturn([1]);
// Then it will load the provision
$provision = $this->getMockBuilder('\\Drupal\\opencase_cases\\Entity\\OCCaseProvision')->disableOriginalConstructor()->getMock();
$storage->expects($this->once())->method('load')->with(1)->willReturn($provision);
// Then it will check the role field, and find that the role is the one specified
// so it will get the target id of the provider field from the provision and return it as an array
$roleField = $this->getMockBuilder('\\Drupal\\COre\\Field\\FieldItemListInterface')->disableOriginalConstructor()->getMock();
$roleField->target_id = '7';
$providerField = $this->getMockBuilder('\\Drupal\\COre\\Field\\FieldItemListInterface')->disableOriginalConstructor()->getMock();
$providerField->target_id = '45';
$provision->expects($this->any())->method('get')->withConsecutive(['oc_case_provider_role'], ['oc_provider'])->willReturnMap(
[['oc_provider', $providerField], ['oc_case_provider_role', $roleField]]
);
$ids = $this->case->getCaseProviderIds(7);
$this->assertTrue($ids == [45]);
}
public function testGetCaseProviderIds_SingleCaseProvision_RoleSpecifiedAndNotMatched(): void{
// It will first get the id of the case provision that references this case
$storage = $this->getStorage($this->etm, 'oc_case_provision');
$query = $this->getQuery($storage);
$this->case->expects($this->once())->method('id')->willReturn(5);
$query->expects($this->once())->method('condition')->with('oc_case.target_id', 5);
$query->expects($this->once())->method('execute')->willReturn([1]);
// Then it will load the provision
$provision = $this->getMockBuilder('\\Drupal\\opencase_cases\\Entity\\OCCaseProvision')->disableOriginalConstructor()->getMock();
$storage->expects($this->once())->method('load')->with(1)->willReturn($provision);
// Then it will check the role field, and find that the role is *not* the one specified
// so it will return nothing
$roleField = $this->getMockBuilder('\\Drupal\\COre\\Field\\FieldItemListInterface')->disableOriginalConstructor()->getMock();
$roleField->target_id = '7';
$providerField = $this->getMockBuilder('\\Drupal\\COre\\Field\\FieldItemListInterface')->disableOriginalConstructor()->getMock();
$providerField->target_id = '45';
$provision->expects($this->any())->method('get')->withConsecutive(['oc_case_provider_role'], ['oc_provider'])->willReturnMap(
[['oc_provider', $providerField], ['oc_case_provider_role', $roleField]]
);
$ids = $this->case->getCaseProviderIds(8);
$this->assertTrue($ids == []);
}
}

View File

@ -0,0 +1,60 @@
<?php declare(strict_types = 1);
namespace Drupal\Tests\opencase\Unit;
use Drupal\Tests\UnitTestCase;
use Drupal\Core\Form\FormState;
use Drupal\Tests\opencase\Unit\EntityTrait;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\opencase_cases\Form\OCCaseRevisionRevertForm;
use Drupal\opencase_entities\Form\OCActorRevisionRevertForm;
use Drupal\opencase_entities\Form\OCActivityRevisionRevertForm;
use Drupal\opencase_entities\Form\OCOrganisationRevisionRevertForm;
class RevisionRevertFormTest extends UnitTestCase{
use EntityTrait;
public function setUp(): void {
$entityTypeManager = $this->getEntityTypeManager();
$storage = $this->getStorage($entityTypeManager);
$dateFormatter = $this->getMockBuilder('\\Drupal\\Core\\Datetime\\DateFormatterInterface')->disableOriginalConstructor()->getMock();
$revision = $this->getMockBuilder('\\Drupal\\opencase_entities\\Entity\OCActivity')->disableOriginalConstructor()->getMock();
$request = new Request([], [], [], [], [], [], [], json_encode([
'foo' => 'bar'
]));
$requestStack = new RequestStack();
$requestStack->push($request);
$dateFormatter->method('format');
$storage->method('loadRevision')->willReturn($revision);
$this->container = $this->getContainer([
'entity_type.manager'=> $entityTypeManager,
'date.formatter' => $dateFormatter,
'string_translation'=> self::getStringTranslationStub(),
'request_stack'=> $requestStack
]);
}
public function testBuildFormForRevertingActivity():void {
$this->reverter = OCActivityRevisionRevertForm::create($this->container);
$form = [];
$this->assertTrue(is_array($this->reverter->buildForm($form, new FormState())));
}
public function testBuildFormForRevertingActor():void {
$this->reverter = OCActorRevisionRevertForm::create($this->container);
$form = [];
$this->assertTrue(is_array($this->reverter->buildForm($form, new FormState())));
}
public function testBuildFormForRevertingCase():void {
$this->reverter = OCCaseRevisionRevertForm::create($this->container);
$form = [];
$this->assertTrue(is_array($this->reverter->buildForm($form, new FormState())));
}
public function testBuildFormForRevertingOrganisation():void {
$this->reverter = OCOrganisationRevisionRevertForm::create($this->container);
$form = [];
$this->assertTrue(is_array($this->reverter->buildForm($form, new FormState())));
}
}

View File

@ -7,42 +7,39 @@ use Drupal\opencase\TimeBasedFieldUpdater;
class TimeBasedFieldUpdaterTest extends UnitTestCase{
use EntityTrait;
function setUp():void {
/** @var \Drupal\opencase\Utils&\PHPUnit\Framework\MockObject\MockObject $utils */
$this->utils = $this->getMockBuilder('\\Drupal\\opencase\\Utils')->disableOriginalConstructor()->getMock();
/** @var \Drupal\core\Entity\EntityTypeManagerInterface&\PHPUnit\Framework\MockObject\MockObject $entityTypeManager */
$this->entityTypeManager = $this->getMockBuilder('\\Drupal\\Core\\Entity\\EntityTypeManager')->disableOriginalConstructor()->getMock();
$this->storage = $this->getMockBuilder('\\Drupal\\Core\\Entity\\EntityStorageInterface')->getMock();
$this->query = $this->getMockBuilder('\\Drupal\\Core\\Entity\\Query\\QueryInterface')->getMock();
$this->entityTypeManager->method('getStorage')->willReturn($this->storage);
$this->storage->method('getQuery')->willReturn($this->query);
$this->updater = new TimeBasedFieldUpdater($this->entityTypeManager, $this->utils, 'dummy_entity_type', 'dummy_bundle', 'dummy_date_field');
$this->etm = $this->getEntityTypeManager();
$this->storage = $this->getStorage($this->etm);
$this->query = $this->getQuery($this->storage);
$this->updater = new TimeBasedFieldUpdater($this->etm, 'dummy_entity_type', 'dummy_bundle', 'dummy_date_field');
}
function testFieldIsUpdatedOnEntityReturnedByQuery():void {
$this->query->method('execute')->willReturn([1]);
$this->query->method('execute')->willReturn(['1']);
$this->entity = $this->getMockBuilder('\\Drupal\\Core\\Entity\\EntityBase')->disableOriginalConstructor()->getMock();
$this->storage->expects($this->once())->method('load')->with(1)->willReturn($this->entity);
$this->updater->update([], '3 months', ['dummy_field' => 4]);
$this->assertEquals($this->entity->dummy_field, 4);
}
function testFieldIsUpdatedOnAllEntitiesReturnedByQuery():void {
$this->query->method('execute')->willReturn([1, 2]);
$this->entity = $this->getMockBuilder('\\Drupal\\Core\\Entity\\EntityBase')->disableOriginalConstructor()->getMock();
$this->entity2 = $this->getMockBuilder('\\Drupal\\Core\\Entity\\EntityBase')->disableOriginalConstructor()->getMock();
$this->storage->method('load')->willReturnMap([[1, $this->entity], [2, $this-> entity2]]);
$this->query->method('execute')->willReturn(['1', '2']);
$entity = $this->getEntity();
$entity2 = $this->getEntity();
$this->storage->method('load')->willReturnMap([['1', $entity], ['2', $entity2]]);
$this->updater->update([], '3 months', ['dummy_field' => 4]);
$this->assertEquals($this->entity->dummy_field, 4);
$this->assertEquals($this->entity2->dummy_field, 4);
$this->assertEquals($entity->dummy_field, 4);
$this->assertEquals($entity2->dummy_field, 4);
}
function testMultipleFieldsAreUpdated(): void {
$this->query->method('execute')->willReturn([1]);
$this->entity = $this->getMockBuilder('\\Drupal\\Core\\Entity\\EntityBase')->disableOriginalConstructor()->getMock();
$this->storage->expects($this->once())->method('load')->with(1)->willReturn($this->entity);
$this->query->method('execute')->willReturn(['1']);
$entity = $this->getEntity();
$this->storage->expects($this->once())->method('load')->with(1)->willReturn($entity);
$this->updater->update([], '3 months', ['dummy_field' => 4, 'dummy_field_2' => 5]);
$this->assertEquals($this->entity->dummy_field, 4);
$this->assertEquals($this->entity->dummy_field_2, 5);
$this->assertEquals($entity->dummy_field, 4);
$this->assertEquals($entity->dummy_field_2, 5);
}