Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clients endpoint pagination and improvements #256

Merged
merged 4 commits into from
Jun 4, 2018

Conversation

joshcanhelp
Copy link
Contributor

  • Add pagination to getAll method via page and per_page parameters.
  • Add application type to getAll method via app_type parameter and app_type constants.
  • Change apiClient fluent methods to explicit.
  • Add validation for required 'name' parameter in create method.
  • Add docblocks throughout Clients.
  • Add additional testing for Clients and BasicCrudTest.

@joshcanhelp joshcanhelp force-pushed the add-clients-pagination-apptype-tests branch 2 times, most recently from cee43fb to 0d6c50a Compare May 31, 2018 17:53
Add pagination to getAll method via page and per_page parameters. Add
application type to getAll method via app_type parameter and app_type
constants. Change apiClient fluent methods to explicit. Add
validation for required 'name' parameter in create method. Add
docblocks throughout Clients. Add additional testing for Clients
and BasicCrudTest.
$fields = implode(',', $fields);
}
$request->withParam('fields', $fields);
}

if ($include_fields !== null)
{
if (null !== $include_fields) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason to invert the null conditions?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yoda conditionals, they are.

*/
public function getAll($fields = null, $include_fields = null)
public function getAll($fields = null, $include_fields = null, $app_type = null, $page = 0, $per_page = null)
Copy link
Contributor

@lbalmaceda lbalmaceda Jun 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so you're changing the existing method's signature. I guess because you're setting default values on the side of each parameter, calling e.g. getAll("name,address", true) will continue to work, not introducing breaking changes on this change right?
Separate from that, would it make sense to have a dedicated parameter+object for "client properties" so you keep the parameter count low even when new parameters are introduced to the endpoint? You'd need to keep fields and include_fields since those where there before. i.e. would you keep adding parameters to this "getAll" signature after they are added on the server side?

Also, note is missing "is_global", "is_first_party", "include_totals". This function is already executing the request (call) so the user is not able to add those if he/she wants.

* @param null|string|array $include_fields
* Allowed app types for self::getAll().
*/
const APP_TYPE_NATIVE = 'native';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO since "app_type" is an optional parameter you can request to filter the result and not something you're required to specify to just "get a client" (in opposition to the email_templates endpoints where this was the ID), this is only helpful for people who want to use this param as a filter. Which, is probably a low number of people. It will do no harm to keep it, and TBH I don't think there will be any new app type nor that the types change in the future. But consider removing them and just explaining in the javadocs what are the allowed values.

{
if (is_array($fields))
{
if (!empty($fields)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty worked for null values too, right?

*
* @return mixed
*/
protected function getAll($crud_api, $created_entity)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is crud_api a parameter, shouldn't that one be common to all the test file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will rename the getAll() for the test class.


// Test a generic "get entity" method.
$got_entity = $crud_api->get($created_entity_id);
$this->afterCreate($got_entity);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are you calling "after create" after a "get one"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add a compare method to check against created entity.

$this->afterCreate($got_entity);

// Test a generic "get all entities" method for this API client.
$all_entities = $this->getAll($crud_api, $created_entity);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this call passing the crud api instead of calling getAll over that api in the first place? like you do on the rest of the methods..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will set $crud_api as a property of the class.

protected function getCreateBody()
{
return [
'name' => $this->create_client_name,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just put all this body data on a JSON file and read it or even a single parameter instead of having many of them defined above? it looks much cleaner IMO.

$fields[] = $this->id_name;

// Check that pagination works.
$all_results = $client->getAll($fields, true, $this->create_app_type, 1, 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is getting page 1 (of 0 based) and 1 result per page. If a single client exists, that one would belong to page 0 right? So this is returning the second client. Is that assumption OK ?

return ['name' => $client_name, 'sso' => false];
// If we want to check for the created result, we need all Clients.
if ($this->findCreatedItem) {
$all_results = $client->getAll($fields, true, $this->create_app_type, 0, 100);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find a waste of resources to make 2 consecutive calls to get them. Just get them all on the first call and that's it.. If you need to test that the page params are being set correctly, just check that on the ongoing request body.

@joshcanhelp joshcanhelp force-pushed the add-clients-pagination-apptype-tests branch from c6877a6 to 5f1d7bc Compare June 4, 2018 15:19
@joshcanhelp joshcanhelp force-pushed the add-clients-pagination-apptype-tests branch from 5f1d7bc to 82e7b10 Compare June 4, 2018 16:24
Copy link
Contributor

@lbalmaceda lbalmaceda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -286,6 +286,17 @@ public function withParams($params) {
return $this;
}

/**
* @param array $params
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this a dict?

@@ -286,6 +286,20 @@ public function withParams($params) {
return $this;
}

/**
* Add URL parameters using $key => $value array.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this a dict?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lbalmaceda - Yes, just being explicit. There's another function that looks for an array of arrays with key and value keys

$request = $this->apiClient->get()
->clients();
// Set additional parameters first so they are over-written by function parameters.
$params = $add_params;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if $add_params is null? this would make following interactions with this element fail

{
$request = $this->apiClient->get()
->clients();
// Set additional parameters first so they are over-written by function parameters.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is fine, but would be nice to get it clearer on the docblock for this add_params param. e.g. "the values specified here are overwritten by the previous params" or something like that

*/
public function getAll($fields = null, $include_fields = null)
public function getAll($fields = null, $include_fields = null, $page = 0, $per_page = null, $add_params = [])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you kept pagination params separated so they are used and not ignored, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

{
// Test a generic "create entity" method for this API client.
$created_entity = $this->api->create($this->getCreateBody());
$created_entity_id = $this->getId($created_entity);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this line is used not in the line right next below this one, i'll swap this line and the one below.

protected function getAllEntities($created_entity)
{
$fields = array_keys($this->getCreateBody());
$fields[] = $this->id_name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's this line doing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sure we have the ID as well so the findCreatedItem loop will work properly.

$this->assertLessThan($many_results_per_page, count($many_results));

// Make sure our paged result above appears in the right place.
$this->assertEquals($paged_results[0][$this->id_name], $many_results[$page_num][$this->id_name]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at a first glance it looked wrong to use $page_num but it's fine. Please add another comment line saying something like "because we previously requested 1 per page, $page_num represents the expected item in the $paged_results"

@joshcanhelp joshcanhelp merged commit e5ba87d into master Jun 4, 2018
@joshcanhelp joshcanhelp deleted the add-clients-pagination-apptype-tests branch June 4, 2018 22:12
@github-actions
Copy link
Contributor

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants