Router::prefix('api/v1', function (RouteBuilder $routes) {
$routes->extensions(['json', 'xml']);
- $routes->resources('Users');
+ $routes->resources('Users');
$routes->resources('Connectors', function(RouteBuilder $routes) {
- $routes->resources('Services');
+ $routes->resources('Services');
});
+ $routes->resources('Subscriptions');
});
Router::scope('/', function (RouteBuilder $routes) {
*/
class ServicesController extends AppController {
+ public $paginate = [
+ 'page' => 1,
+ 'limit' => 20,
+ 'maxLimit' => 100,
+ 'fields' => [
+ 'id', 'name'
+ ],
+ 'sortWhitelist' => [
+ 'id', 'name'
+ ]
+ ];
+
/**
* Index method
*
--- /dev/null
+<?php
+
+namespace App\Controller\Api\V1;
+
+use App\Controller\AppController;
+use App\Network\Exception\SubscriptionNotFoundException;
+
+/**
+ * Subscriptions Controller
+ *
+ * @property \App\Model\Table\SubscriptionsTable $Subscriptions
+ */
+class SubscriptionsController extends AppController {
+
+ public $paginate = [
+ 'page' => 1,
+ 'limit' => 20,
+ 'maxLimit' => 100,
+ 'fields' => [
+ 'id', 'name'
+ ],
+ 'sortWhitelist' => [
+ 'id', 'name'
+ ]
+ ];
+
+ /**
+ * Index method
+ *
+ * @return \Cake\Network\Response|null
+ */
+ public function index() {
+ $this->request->allowMethod('get');
+
+ $subscriptions = $this->paginate($this->Subscriptions);
+
+ $pagination = $this->request->params['paging']['Subscriptions'];
+
+ $paginationResponse = [
+ 'page_count' => $pagination['pageCount'],
+ 'current_page' => $pagination['page'],
+ 'has_next_page' => $pagination['nextPage'],
+ 'has_prev_page' => $pagination['prevPage'],
+ 'count' => $pagination['count'],
+ 'limit' => $pagination['limit']
+ ];
+
+ $this->set('pagination', $paginationResponse);
+ $this->set('subscriptions', $subscriptions);
+ }
+
+ /**
+ * View method
+ *
+ * @param string $id Subscription id.
+ * @return \Cake\Network\Response|null
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function view($id) {
+ $this->request->allowMethod('get');
+ try {
+ $subscription = $this->Subscriptions->get($id, [
+ 'contain' => ['Services']
+ ]);
+ }
+ catch (\Exception $e) {
+ throw new SubscriptionNotFoundException("The subscription with the id $id does not exist");
+ }
+ $this->set('subscription', $subscription);
+ $this->set('_serialize', 'subscription');
+ }
+
+ /**
+ * Add method
+ *
+ * @return \Cake\Network\Response|void Redirects on successful add, renders view otherwise.
+ */
+ public function add() {
+ $this->request->allowMethod('post');
+
+ $subscription = $this->Subscriptions->newEntity($this->request->data);
+ if ($this->Subscriptions->save($subscription)) {
+ $this->response->statusCode(201);
+ $this->set('subscription', $subscription);
+ $this->set('_serialize', 'subscription');
+ }
+ else {
+ $this->response->statusCode(400);
+ throw new ValidationException($subscription);
+ }
+ }
+
+ /**
+ * Edit method
+ *
+ * @param string $id Subscription id.
+ * @return \Cake\Network\Response|void Redirects on successful edit, renders view otherwise.
+ * @throws \Cake\Network\Exception\NotFoundException When record not found.
+ */
+ public function edit($id) {
+ $this->request->allowMethod('put');
+
+ try {
+ $subscription = $this->Subscriptions->get($id);
+ }
+ catch (\Exception $e) {
+ throw new SubscriptionNotFoundException("The subscription with the id $id does not exist");
+ }
+
+ $subscription = $this->Subscriptions->patchEntity($subscription, $this->request->data);
+ if ($this->Subscriptions->save($subscription)) {
+ $this->set('subscription', $subscription);
+ $this->set('_serialize', 'subscription');
+ }
+ else {
+ throw new ValidationException($subscription);
+ }
+ }
+
+ /**
+ * Delete method
+ *
+ * @param string $id Subscription id.
+ * @return \Cake\Network\Response|null Redirects to index.
+ * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
+ */
+ public function delete($id) {
+ $this->request->allowMethod('delete');
+ try {
+ $subscription = $this->Subscriptions->get($id);
+ }
+ catch (\Exception $e) {
+ throw new SubscriptionNotFoundException("The subscription with the id $id does not exist");
+ }
+ $this->Subscriptions->delete($subscription);
+ $this->response->statusCode(204);
+ }
+
+}
'id' => false,
];
+ /**
+ * Fields that are excluded from JSON an array versions of the entity.
+ *
+ * @var array
+ */
+ protected $_hidden = [
+ // Hide it from Subscriptions as it is not a useful information
+ '_joinData'
+ ];
+
}
--- /dev/null
+<?php
+
+namespace App\Model\Entity;
+
+use Cake\ORM\Entity;
+
+/**
+ * Subscription Entity.
+ *
+ * @property int $id
+ * @property string $name
+ * @property \App\Model\Entity\LocalGovernment[] $local_governments
+ * @property \App\Model\Entity\Service[] $services
+ */
+class Subscription extends Entity {
+
+ /**
+ * Fields that can be mass assigned using newEntity() or patchEntity().
+ *
+ * Note that when '*' is set to true, this allows all unspecified fields to
+ * be mass assigned. For security purposes, it is advised to set '*' to false
+ * (or remove it), and explicitly make individual fields accessible as needed.
+ *
+ * @var array
+ */
+ protected $_accessible = [
+ '*' => true,
+ 'id' => false,
+ ];
+
+}
--- /dev/null
+<?php
+
+namespace App\Model\Table;
+
+use App\Model\Entity\Subscription;
+use Cake\ORM\Query;
+use Cake\ORM\RulesChecker;
+use Cake\ORM\Table;
+use Cake\Validation\Validator;
+
+/**
+ * Subscriptions Model
+ *
+ * @property \Cake\ORM\Association\HasMany $LocalGovernments
+ * @property \Cake\ORM\Association\BelongsToMany $Services
+ */
+class SubscriptionsTable extends Table {
+
+ /**
+ * Initialize method
+ *
+ * @param array $config The configuration for the Table.
+ * @return void
+ */
+ public function initialize(array $config) {
+ parent::initialize($config);
+
+ $this->table('subscriptions');
+ $this->displayField('name');
+ $this->primaryKey('id');
+
+ $this->hasMany('LocalGovernments', [
+ 'foreignKey' => 'subscription_id'
+ ]);
+ $this->belongsToMany('Services', [
+ 'foreignKey' => 'subscription_id',
+ 'targetForeignKey' => 'service_id',
+ 'joinTable' => 'subscriptions_services'
+ ]);
+ }
+
+ /**
+ * Default validation rules.
+ *
+ * @param \Cake\Validation\Validator $validator Validator instance.
+ * @return \Cake\Validation\Validator
+ */
+ public function validationDefault(Validator $validator) {
+ $validator
+ ->integer('id')
+ ->allowEmpty('id', 'create');
+
+ $validator
+ ->requirePresence('name', 'create')
+ ->notEmpty('name')
+ ->add('name', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
+
+ return $validator;
+ }
+
+ /**
+ * Returns a rules checker object that will be used for validating
+ * application integrity.
+ *
+ * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
+ * @return \Cake\ORM\RulesChecker
+ */
+ public function buildRules(RulesChecker $rules) {
+ $rules->add($rules->isUnique(['name']));
+ return $rules;
+ }
+
+}
--- /dev/null
+<?php
+
+namespace App\Network\Exception;
+
+use Cake\Network\Exception\NotFoundException;
+
+class SubscriptionNotFoundException extends NotFoundException {
+
+}
--- /dev/null
+<?php
+
+namespace App\Test\Fixture;
+
+use Cake\TestSuite\Fixture\TestFixture;
+
+/**
+ * SubscriptionsFixture
+ *
+ */
+class SubscriptionsFixture extends TestFixture {
+
+ /**
+ * Fields
+ *
+ * @var array
+ */
+ // @codingStandardsIgnoreStart
+ public $fields = [
+ 'id' => ['type' => 'integer', 'length' => 10, 'autoIncrement' => true, 'default' => null, 'null' => false, 'comment' => null, 'precision' => null, 'unsigned' => null],
+ 'name' => ['type' => 'string', 'length' => 255, 'default' => null, 'null' => false, 'comment' => null, 'precision' => null, 'fixed' => null],
+ '_constraints' => [
+ 'primary' => ['type' => 'primary', 'columns' => ['id'], 'length' => []],
+ 'subscriptions_name_UNIQUE' => ['type' => 'unique', 'columns' => ['name'], 'length' => []],
+ ],
+ ];
+ // @codingStandardsIgnoreEnd
+
+ /**
+ * Records
+ *
+ * @var array
+ */
+ public $records = [
+ [
+ 'id' => 1,
+ 'name' => 'ACTES/HELIOS',
+ ],
+ [
+ 'id' => 2,
+ 'name' => 'SIGNATURE',
+ ],
+ ];
+
+}
--- /dev/null
+<?php
+namespace App\Test\Fixture;
+
+use Cake\TestSuite\Fixture\TestFixture;
+
+/**
+ * SubscriptionsServicesFixture
+ *
+ */
+class SubscriptionsServicesFixture extends TestFixture
+{
+
+ /**
+ * Fields
+ *
+ * @var array
+ */
+ // @codingStandardsIgnoreStart
+ public $fields = [
+ 'subscription_id' => ['type' => 'integer', 'length' => 10, 'default' => null, 'null' => false, 'comment' => null, 'precision' => null, 'unsigned' => null, 'autoIncrement' => null],
+ 'service_id' => ['type' => 'integer', 'length' => 10, 'default' => null, 'null' => false, 'comment' => null, 'precision' => null, 'unsigned' => null, 'autoIncrement' => null],
+ '_indexes' => [
+ 'subscriptions_services_fk_subscriptions_has_services_subscripti' => ['type' => 'index', 'columns' => ['subscription_id'], 'length' => []],
+ 'subscriptions_services_fk_subscriptions_has_services_services1_' => ['type' => 'index', 'columns' => ['service_id'], 'length' => []],
+ ],
+ '_constraints' => [
+ 'primary' => ['type' => 'primary', 'columns' => ['subscription_id', 'service_id'], 'length' => []],
+ ],
+ ];
+ // @codingStandardsIgnoreEnd
+
+ /**
+ * Records
+ *
+ * @var array
+ */
+ public $records = [
+ [
+ 'subscription_id' => 1,
+ 'service_id' => 1
+ ],
+ [
+ 'subscription_id' => 1,
+ 'service_id' => 2
+ ],
+ [
+ 'subscription_id' => 1,
+ 'service_id' => 3
+ ],
+ [
+ 'subscription_id' => 2,
+ 'service_id' => 4
+ ],
+ ];
+}
--- /dev/null
+<?php
+
+namespace App\Test\TestCase\Controller\Api\V1;
+
+use App\Test\TestCase\Controller\Api\V1\ApiIntegrationTestCase;
+
+/**
+ * App\Controller\SubscriptionsController Test Case
+ */
+class SubscriptionsControllerTest extends ApiIntegrationTestCase {
+
+ /**
+ * Fixtures
+ *
+ * @var array
+ */
+ public $fixtures = [
+ 'app.subscriptions',
+ 'app.subscriptions_services',
+ 'app.services',
+ ];
+ public $autoFixtures = false;
+
+ public function testWhenGettingAllSubscriptions() {
+ $this->loadFixtures('Subscriptions');
+ $this->iSendAGetRequestTo('/subscriptions.json');
+ $this->theResponseCodeShouldBe(200);
+
+ $expected = [
+ 'subscriptions' => [
+ [
+ 'id' => 1, 'name' => 'ACTES/HELIOS'
+ ],
+ [
+ 'id' => 2, 'name' => 'SIGNATURE'
+ ]
+ ],
+ 'pagination' => [
+ 'page_count' => 1,
+ 'current_page' => 1,
+ 'has_next_page' => FALSE,
+ 'has_prev_page' => FALSE,
+ 'count' => 2,
+ 'limit' => null
+ ]
+ ];
+ $expectedBody = $this->getExpectedValue($expected);
+ $this->theResponseBodyShouldBe($expectedBody);
+ }
+
+ public function testWhenGettingNoSubscription() {
+ $this->iSendAGetRequestTo('/subscriptions.json');
+ $this->theResponseCodeShouldBe(200);
+
+ $expected = [
+ 'subscriptions' => [],
+ 'pagination' => [
+ 'page_count' => 0,
+ 'current_page' => 1,
+ 'has_next_page' => FALSE,
+ 'has_prev_page' => FALSE,
+ 'count' => 0,
+ 'limit' => null
+ ]
+ ];
+ $expectedBody = $this->getExpectedValue($expected);
+
+ $this->theResponseBodyShouldBe($expectedBody);
+ }
+
+ public function testWhenGettingASubscription() {
+ $this->loadFixtures('Subscriptions', 'Services', 'SubscriptionsServices');
+ $this->iSendAGetRequestTo('/subscriptions/2.json');
+ $this->theResponseCodeShouldBe(200);
+
+ $expected = [
+ 'id' => 2,
+ 'name' => 'SIGNATURE',
+ 'services' => [
+ [
+ 'id' => 4,
+ 'name' => 'signature',
+ 'connector_id' => 2
+ ]
+ ]
+ ];
+ $expectedBody = $this->getExpectedValue($expected);
+
+ $this->theResponseBodyShouldBe($expectedBody);
+ }
+
+ public function testWhenDeletingASubscription() {
+ $this->loadFixtures('Subscriptions');
+ $this->iSendADeleteRequestTo('/subscriptions/1.json');
+ $this->theResponseCodeShouldBe(204);
+ }
+
+ public function testWhenDeletingASubscriptionThatDoesNotExist() {
+ $this->loadFixtures('Subscriptions');
+ $this->iSendADeleteRequestTo('/subscriptions/4.json');
+ $this->theResponseCodeShouldBe(404);
+
+ $expected = [
+ 'message' => 'The subscription with the id 4 does not exist',
+ 'url' => '/api/v1/subscriptions/4.json',
+ 'code' => 404
+ ];
+
+ $expectedBody = $this->getExpectedValue($expected);
+
+ $this->theResponseBodyShouldBe($expectedBody);
+ }
+
+ public function testWhenAddingASubscription() {
+ $data = [
+ 'name' => 'test'
+ ];
+ $this->givenIHaveSomeDataToSend($data);
+ $this->iSendAPostRequestTo('/subscriptions.json');
+ }
+
+}
--- /dev/null
+<?php
+namespace App\Test\TestCase\Model\Table;
+
+use App\Model\Table\SubscriptionsTable;
+use Cake\ORM\TableRegistry;
+use Cake\TestSuite\TestCase;
+
+/**
+ * App\Model\Table\SubscriptionsTable Test Case
+ */
+class SubscriptionsTableTest extends TestCase
+{
+
+ /**
+ * Test subject
+ *
+ * @var \App\Model\Table\SubscriptionsTable
+ */
+ public $Subscriptions;
+
+ /**
+ * Fixtures
+ *
+ * @var array
+ */
+ public $fixtures = [
+ 'app.subscriptions',
+ 'app.local_governments',
+ 'app.services',
+ 'app.connectors',
+ 'app.subscriptions_services',
+ 'app.users_memberships',
+ 'app.users_memberships_services'
+ ];
+
+ /**
+ * setUp method
+ *
+ * @return void
+ */
+ public function setUp()
+ {
+ parent::setUp();
+ $config = TableRegistry::exists('Subscriptions') ? [] : ['className' => 'App\Model\Table\SubscriptionsTable'];
+ $this->Subscriptions = TableRegistry::get('Subscriptions', $config);
+ }
+
+ /**
+ * tearDown method
+ *
+ * @return void
+ */
+ public function tearDown()
+ {
+ unset($this->Subscriptions);
+
+ parent::tearDown();
+ }
+
+ /**
+ * Test initialize method
+ *
+ * @return void
+ */
+ public function testInitialize()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test validationDefault method
+ *
+ * @return void
+ */
+ public function testValidationDefault()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+
+ /**
+ * Test buildRules method
+ *
+ * @return void
+ */
+ public function testBuildRules()
+ {
+ $this->markTestIncomplete('Not implemented yet.');
+ }
+}