Refactored endpoint to get summit push notifications

GET /api/v1/summits/{id}/notifications

* Expands
** owner
** approved_by

* Filters
** channel ['=='] (sometimes|in:EVERYONE,SPEAKERS,ATTENDEES,MEMBERS,SUMMIT,EVENT,GROUP)
** sent_date ['>', '<', '<=', '>=', '=='] (sometimes|date_format:U)
** created ['>', '<', '<=', '>=', '=='] (sometimes|date_format:U)
** is_sent ['=='] (sometimes|boolean)
** approved ['=='] (sometimes|boolean)
** event_id ['=='] (sometimes|integer)

* Order
** sent_date
** created
** id

Change-Id: Idb93b9a12817c3385150cbb69914b3a089ace6d1
This commit is contained in:
Sebastian Marcet 2018-04-16 13:01:51 -03:00
parent a7a8877ace
commit 651a16d8d2
14 changed files with 257 additions and 109 deletions

View File

@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\Http\Utils\PagingConstants;
use models\exceptions\EntityNotFoundException;
use models\exceptions\ValidationException;
use models\oauth2\IResourceServerContext;
@ -20,13 +20,13 @@ use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Input;
use models\summit\ISummitRepository;
use models\summit\SummitPushNotificationChannel;
use utils\Filter;
use utils\FilterParser;
use utils\FilterParserException;
use utils\OrderParser;
use utils\PagingInfo;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Request;
/**
* Class OAuth2SummitNotificationsApiController
* @package App\Http\Controllers
@ -49,7 +49,8 @@ class OAuth2SummitNotificationsApiController extends OAuth2ProtectedController
ISummitRepository $summit_repository,
ISummitNotificationRepository $notification_repository,
IResourceServerContext $resource_server_context
) {
)
{
parent::__construct($resource_server_context);
$this->repository = $notification_repository;
$this->summit_repository = $summit_repository;
@ -68,11 +69,10 @@ class OAuth2SummitNotificationsApiController extends OAuth2ProtectedController
$values = Input::all();
$rules = array
(
$rules = [
'page' => 'integer|min:1',
'per_page' => 'required_with:page|integer|min:5|max:100',
);
'per_page' => sprintf('required_with:page|integer|min:%s|max:%s', PagingConstants::MinPageSize, PagingConstants::MaxPageSize),
];
$validation = Validator::make($values, $rules);
@ -83,7 +83,7 @@ class OAuth2SummitNotificationsApiController extends OAuth2ProtectedController
// default values
$page = 1;
$per_page = 5;
$per_page = PagingConstants::DefaultPageSize;
if (Input::has('page')) {
$page = intval(Input::get('page'));
@ -97,28 +97,32 @@ class OAuth2SummitNotificationsApiController extends OAuth2ProtectedController
'sent_date' => ['>', '<', '<=', '>=', '=='],
'created' => ['>', '<', '<=', '>=', '=='],
'is_sent' => ['=='],
'approved' => ['=='],
'event_id' => ['=='],
]);
$channels = $filter->getFlatFilter("channel");
// validate that channel filter, if present if for a public one
if(!is_null($channels) && is_array($channels)){
foreach ($channels as $element){
if(!SummitPushNotificationChannel::isPublicChannel($element->getValue()))
throw new ValidationException(sprintf("%s channel is not public!", $element->getValue()));
}
}
}
if(is_null($filter)) $filter = new Filter();
$filter->validate([
'channel' => 'sometimes|in:EVERYONE,SPEAKERS,ATTENDEES,MEMBERS,SUMMIT,EVENT,GROUP',
'sent_date' => 'sometimes|date_format:U',
'created' => 'sometimes|date_format:U',
'is_sent' => 'sometimes|boolean',
'approved' => 'sometimes|boolean',
'event_id' => 'sometimes|integer',
]);
$order = null;
if (Input::has('order'))
{
$order = OrderParser::parse(Input::get('order'), array
(
$order = OrderParser::parse(Input::get('order'), [
'sent_date',
'created',
'id',
));
]);
}
$result = $this->repository->getAllByPageBySummit($summit, new PagingInfo($page, $per_page), $filter, $order);
@ -138,10 +142,6 @@ class OAuth2SummitNotificationsApiController extends OAuth2ProtectedController
Log::warning($ex2);
return $this->error412($ex2->getMessages());
}
catch(FilterParserException $ex3){
Log::warning($ex3);
return $this->error412($ex3->getMessages());
}
catch (\Exception $ex)
{
Log::error($ex);

View File

@ -93,7 +93,6 @@ final class OAuth2SummitRSVPTemplatesApiController extends OAuth2ProtectedContro
$values = Input::all();
$rules = [
'page' => 'integer|min:1',
'per_page' => sprintf('required_with:page|integer|min:%s|max:%s', PagingConstants::MinPageSize, PagingConstants::MaxPageSize),
];
@ -113,7 +112,7 @@ final class OAuth2SummitRSVPTemplatesApiController extends OAuth2ProtectedContro
// default values
$page = 1;
$per_page = PagingConstants::DefaultPageSize;;
$per_page = PagingConstants::DefaultPageSize;
if (Input::has('page')) {
$page = intval(Input::get('page'));

View File

@ -237,8 +237,8 @@ Route::group([
});
// notifications
Route::group(array('prefix' => 'notifications'), function () {
Route::get('', 'OAuth2SummitNotificationsApiController@getAll');
Route::group(['prefix' => 'notifications'], function () {
Route::get('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitNotificationsApiController@getAll']);
});
// speakers
@ -249,7 +249,7 @@ Route::group([
Route::group(['prefix' => '{speaker_id}'], function () {
Route::get('', 'OAuth2SummitSpeakersApiController@getSummitSpeaker')->where('speaker_id', 'me|[0-9]+');
Route::put('',[ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitSpeakersApiController@updateSpeakerBySummit'])->where('speaker_id', 'me|[0-9]+');
Route::put('', [ 'middleware' => 'auth.user:administrators|summit-front-end-administrators', 'uses' => 'OAuth2SummitSpeakersApiController@updateSpeakerBySummit'])->where('speaker_id', 'me|[0-9]+');
});
});

View File

@ -0,0 +1,72 @@
<?php namespace App\ModelSerializers;
/**
* Copyright 2018 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use models\main\PushNotificationMessage;
use ModelSerializers\SerializerRegistry;
use ModelSerializers\SilverStripeSerializer;
/**
* Class PushNotificationMessageSerializer
* @package App\ModelSerializers
*/
class PushNotificationMessageSerializer extends SilverStripeSerializer
{
protected static $array_mappings = [
'Message' => 'message:json_string',
'Priority' => 'priority:json_string',
'Created' => 'created:datetime_epoch',
'SentDate' => 'sent_date:datetime_epoch',
'IsSent' => 'is_sent:json_boolean',
'Approved' => 'approved:json_boolean',
'OwnerId' => 'owner_id:json_int',
'ApprovedById' => 'approved_by_id:json_int',
];
/**
* @param null $expand
* @param array $fields
* @param array $relations
* @param array $params
* @return array
*/
public function serialize($expand = null, array $fields = [], array $relations = [], array $params = [])
{
$notification = $this->object;
if(! $notification instanceof PushNotificationMessage) return [];
$values = parent::serialize($expand, $fields, $relations, $params);
if (!empty($expand)) {
$exp_expand = explode(',', $expand);
foreach ($exp_expand as $relation) {
switch (trim($relation)) {
case 'owner': {
if(!$notification->hasOwner()) continue;
unset($values['owner_id']);
$values['owner'] = SerializerRegistry::getInstance()->getSerializer($notification->getOwner())->serialize();
}
break;
case 'approved_by': {
if(!$notification->hasApprovedBy()) continue;
unset($values['approved_by_id']);
$values['approved_by'] = SerializerRegistry::getInstance()->getSerializer($notification->getApprovedBy())->serialize();
}
break;
}
}
}
return $values;
}
}

View File

@ -34,6 +34,7 @@ use App\ModelSerializers\Marketplace\RemoteCloudServiceSerializer;
use App\ModelSerializers\Marketplace\ServiceOfferedTypeSerializer;
use App\ModelSerializers\Marketplace\SpokenLanguageSerializer;
use App\ModelSerializers\Marketplace\SupportChannelTypeSerializer;
use App\ModelSerializers\PushNotificationMessageSerializer;
use App\ModelSerializers\Software\OpenStackComponentSerializer;
use App\ModelSerializers\Software\OpenStackReleaseSerializer;
use App\ModelSerializers\Summit\AdminSummitSerializer;
@ -177,8 +178,8 @@ final class SerializerRegistry
$this->registry['Group'] = GroupSerializer::class;
$this->registry['Affiliation'] = AffiliationSerializer::class;
$this->registry['Organization'] = OrganizationSerializer::class;
// push notification
$this->registry['PushNotificationMessage'] = PushNotificationMessageSerializer::class;
$this->registry['SummitPushNotification'] = SummitPushNotificationSerializer::class;
// teams

View File

@ -11,6 +11,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use App\ModelSerializers\PushNotificationMessageSerializer;
use models\summit\SummitPushNotification;
use models\summit\SummitPushNotificationChannel;
@ -19,16 +20,12 @@ use models\summit\SummitPushNotificationChannel;
* Class SummitPushNotificationSerializer
* @package ModelSerializers
*/
final class SummitPushNotificationSerializer extends SilverStripeSerializer
final class SummitPushNotificationSerializer extends PushNotificationMessageSerializer
{
protected static $array_mappings = array
(
protected static $array_mappings = [
'Channel' => 'channel:json_string',
'Message' => 'message:json_string',
'SentDate' => 'sent_date:datetime_epoch',
'Created' => 'created:datetime_epoch',
'IsSent' => 'is_sent:json_boolean',
);
'SummitId' => 'summit_id:json_int',
];
/**
* @param null $expand
@ -37,7 +34,7 @@ final class SummitPushNotificationSerializer extends SilverStripeSerializer
* @param array $params
* @return array
*/
public function serialize($expand = null, array $fields = array(), array $relations = array(), array $params = array() )
public function serialize($expand = null, array $fields = [], array $relations = [], array $params = [] )
{
$notification = $this->object;
if(! $notification instanceof SummitPushNotification) return [];
@ -50,6 +47,13 @@ final class SummitPushNotificationSerializer extends SilverStripeSerializer
if($notification->getChannel() == SummitPushNotificationChannel::Group){
$values['group'] = SerializerRegistry::getInstance()->getSerializer($notification->getGroup())->serialize();
}
if($notification->getChannel() == SummitPushNotificationChannel::Members){
$values['recipients'] = [];
foreach ($notification->getRecipients() as $recipient)
$values['recipients'][] = SerializerRegistry::getInstance()->getSerializer($recipient)->serialize();
}
return $values;
}
}

View File

@ -11,16 +11,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Doctrine\ORM\Mapping AS ORM;
use models\utils\SilverstripeBaseModel;
/**
* @ORM\Entity
* @ORM\Table(name="PushNotificationMessage")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="ClassName", type="string")
* @ORM\DiscriminatorMap({"PushNotificationMessage" = "PushNotificationMessage", "SummitPushNotification" = "models\summit\SummitPushNotification", "ChatTeamPushNotificationMessage" = "ChatTeamPushNotificationMessage"})
* @ORM\DiscriminatorMap({
* "PushNotificationMessage" = "PushNotificationMessage",
* "SummitPushNotification" = "models\summit\SummitPushNotification",
* "ChatTeamPushNotificationMessage" = "ChatTeamPushNotificationMessage"
* })
* Class PushNotificationMessage
* @package models\main
*/
@ -97,6 +99,18 @@ class PushNotificationMessage extends SilverstripeBaseModel
}
}
/**
* @return int
*/
public function getApprovedById(){
try{
return $this->approved_by->getId();
}
catch (\Exception $ex){
return 0;
}
}
/**
* @return string
*/
@ -178,6 +192,13 @@ class PushNotificationMessage extends SilverstripeBaseModel
return $this->owner;
}
/**
* @return bool
*/
public function hasOwner(){
return $this->getOwnerId() > 0;
}
/**
* @param Member $owner
*/
@ -242,6 +263,13 @@ class PushNotificationMessage extends SilverstripeBaseModel
return $this->approved_by;
}
/**
* @return bool
*/
public function hasApprovedBy(){
return $this->getApprovedById() > 0;
}
/**
* @param Member $approved_by
*/

View File

@ -0,0 +1,22 @@
<?php namespace App\Models\Foundation\Main\Repositories;
/**
* Copyright 2018 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use models\utils\IBaseRepository;
/**
* Interface IPushNotificationRepository
* @package App\Models\Foundation\Main\Repositories
*/
interface IPushNotificationRepository extends IBaseRepository
{
}

View File

@ -11,18 +11,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use models\utils\IBaseRepository;
use App\Models\Foundation\Main\Repositories\IPushNotificationRepository;
use utils\Filter;
use utils\Order;
use utils\PagingInfo;
use utils\PagingResponse;
/**
* Interface ISummitNotificationRepository
* @package models\summit
*/
interface ISummitNotificationRepository extends IBaseRepository
interface ISummitNotificationRepository extends IPushNotificationRepository
{
/**
* @param Summit $summit

View File

@ -11,12 +11,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
**/
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use models\main\Group;
use models\main\PushNotificationMessage;
/**
* Class SummitPushNotificationChannel
* @package models\summit
@ -63,6 +61,29 @@ class SummitPushNotification extends PushNotificationMessage
*/
private $channel;
/**
* @ORM\ManyToOne(targetEntity="models\summit\SummitEvent")
* @ORM\JoinColumn(name="EventID", referencedColumnName="ID")
* @var SummitEvent
*/
private $summit_event;
/**
* @ORM\ManyToOne(targetEntity="models\main\Group")
* @ORM\JoinColumn(name="GroupID", referencedColumnName="ID")
* @var Group
*/
private $group;
/**
* @ORM\ManyToMany(targetEntity="models\main\Member")
* @ORM\JoinTable(name="SummitPushNotification_Recipients",
* joinColumns={@ORM\JoinColumn(name="SummitPushNotificationID", referencedColumnName="ID")},
* inverseJoinColumns={@ORM\JoinColumn(name="MemberID", referencedColumnName="ID")}
* )
*/
private $recipients;
/**
* @return string
*/
@ -127,29 +148,6 @@ class SummitPushNotification extends PushNotificationMessage
$this->recipients = $recipients;
}
/**
* @ORM\ManyToOne(targetEntity="models\summit\SummitEvent")
* @ORM\JoinColumn(name="EventID", referencedColumnName="ID")
* @var SummitEvent
*/
private $summit_event;
/**
* @ORM\ManyToOne(targetEntity="models\main\Group")
* @ORM\JoinColumn(name="GroupID", referencedColumnName="ID")
* @var Group
*/
private $group;
/**
* @ORM\ManyToMany(targetEntity="models\main\Member")
* @ORM\JoinTable(name="SummitPushNotification_Recipients",
* joinColumns={@ORM\JoinColumn(name="SummitPushNotificationID", referencedColumnName="ID")},
* inverseJoinColumns={@ORM\JoinColumn(name="MemberID", referencedColumnName="ID")}
* )
*/
private $recipients;
/**
* SummitPushNotification constructor.
*/

View File

@ -43,7 +43,8 @@ final class DoctrineSummitNotificationRepository
'channel' => 'n.channel:json_string',
'sent_date' => 'n.sent_date:datetime_epoch',
'created' => 'n.created:datetime_epoch',
'is_sent' => 'n.is_sent:json_int',
'is_sent' => 'n.is_sent:json_boolean',
'approved' => 'n.approved:json_boolean',
];
}

View File

@ -1406,6 +1406,7 @@ class ApiEndpointsSeeder extends Seeder
'route' => '/api/v1/summits/{id}/notifications',
'http_method' => 'GET',
'scopes' => [
sprintf(SummitScopes::ReadAllSummitData, $current_realm),
sprintf(SummitScopes::ReadNotifications, $current_realm)
],
],

View File

@ -1046,44 +1046,6 @@ final class OAuth2SummitApiTest extends ProtectedApiTest
}
public function testGetSummitNotifications()
{
$params = array
(
'id' => 7,
'page' => 1,
'per_page' => 15,
'filter' => [
'channel==' . \models\summit\SummitPushNotificationChannel::Event . ',channel==' . \models\summit\SummitPushNotificationChannel::Group,
],
'order' => '+sent_date'
);
$headers = array
(
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
);
$response = $this->action
(
"GET",
"OAuth2SummitNotificationsApiController@getAll",
$params,
array(),
array(),
array(),
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(200);
$notifications = json_decode($content);
$this->assertTrue(!is_null($notifications));
}
public function testAdd2Favorite($summit_id = 22, $event_id = 18719){
$params = array
(

View File

@ -0,0 +1,62 @@
<?php
/**
* Copyright 2018 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
/**
* Class OAuth2SummitNotificationsApiControllerTest
*/
final class OAuth2SummitNotificationsApiControllerTest extends ProtectedApiTest
{
/**
* @param int $summit_id
* @return mixed
*/
public function testGetApprovedSummitNotifications($summit_id = 24)
{
$params = [
'id' => $summit_id,
'page' => 1,
'per_page' => 15,
'order' => '+sent_date',
'expand' => 'owner,approved_by',
'filter' => [
'approved==1'
],
];
$headers = [
"HTTP_Authorization" => " Bearer " . $this->access_token,
"CONTENT_TYPE" => "application/json"
];
$response = $this->action
(
"GET",
"OAuth2SummitNotificationsApiController@getAll",
$params,
[],
[],
[],
$headers
);
$content = $response->getContent();
$this->assertResponseStatus(200);
$notifications = json_decode($content);
$this->assertTrue(!is_null($notifications));
return $notifications;
}
}