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

feat: send list classes #1629

Merged
merged 11 commits into from
Sep 3, 2024
Merged

feat: send list classes #1629

merged 11 commits into from
Sep 3, 2024

Conversation

dkoo
Copy link
Contributor

@dkoo dkoo commented Aug 29, 2024

All Submissions:

Changes proposed in this Pull Request:

Implements a new Send_List class for abstacting ESP-specific list and sublist data into a single schema. Also implements a Send_Lists class for shared util methods and REST API routes (the latter currently won't work because this PR doesn't include the get_send_lists() methods on each provider class).

To support the new REST API routes, moves the newsletters/v1 namespace and the API permissions callback to the main Newspack_Newsletters class, so these can be shared outside of the Newspack_Newsletters_Subscription class.

How to test the changes in this Pull Request:

  1. Confirm that all tests pass (and review the tests for expected Send_List behavior)
  2. In wp_shell, try the new constructor:
> $send_list = new Newspack\Newsletters\Send_List( [ 'id' => '123', 'name' => 'My Send List', 'type' => 'list', 'entity_type' => 'something', 'count' => 100, 'provider' => 'mailchimp' ] )
= Newspack\Newsletters\Send_List {#14997
    +"provider": "mailchimp",
    +"type": "list",
    +"entity_type": "something",
    +"id": "123",
    +"name": "My Send List",
    +"count": 100,
    +"value": "123",
    +"label": "[SOMETHING] My Send List (100 contacts)",
  }
  1. Try out the new methods:
> $send_list->get_id()
= "123"

> $send_list->get_label()
= "[SOMETHING] My Send List (100 contacts)"

> $send_list->set_name( 'My Send List (renamed)' )
= "My Send List (renamed)"

> $send_list->get_name()
= "My Send List (renamed)"

> Newspack\Newsletters\Send_Lists::matches_search( 'renamed', [ $send_list->get( 'name' ) ] )
= true

> Newspack\Newsletters\Send_Lists::matches_id( [ 123 ], $send_list->get( 'id' ) )
= true

> $send_list->to_array()
= [
    "provider" => "mailchimp",
    "type" => "list",
    "entity_type" => "something",
    "id" => "123",
    "name" => "My Send List",
    "count" => 100,
    "label" => "[SOMETHING] My Send List (100 contacts)",
    "value" => "123",
  ]

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully ran tests with your changes locally?

@dkoo dkoo self-assigned this Aug 29, 2024
@dkoo dkoo requested a review from a team as a code owner August 29, 2024 16:46
@dkoo dkoo changed the title Feat/send lists feat: send list classes Aug 29, 2024
Copy link
Member

@miguelpeixe miguelpeixe left a comment

Choose a reason for hiding this comment

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

The class looks great and I love how clear the tests are!

I have a few comments:

includes/class-send-list.php Outdated Show resolved Hide resolved
includes/class-send-list.php Outdated Show resolved Hide resolved
includes/class-send-list.php Outdated Show resolved Hide resolved
includes/class-send-list.php Outdated Show resolved Hide resolved
includes/class-send-list.php Outdated Show resolved Hide resolved
Copy link

codecov bot commented Aug 30, 2024

Codecov Report

Attention: Patch coverage is 64.00000% with 81 lines in your changes missing coverage. Please review.

Project coverage is 21.85%. Comparing base (05c1e23) to head (59594c3).

Files with missing lines Patch % Lines
includes/class-send-lists.php 25.00% 54 Missing ⚠️
includes/class-send-list.php 90.00% 14 Missing ⚠️
...cludes/class-newspack-newsletters-subscription.php 0.00% 11 Missing ⚠️
includes/class-newspack-newsletters.php 0.00% 2 Missing ⚠️
Additional details and impacted files
@@                     Coverage Diff                      @@
##             epic/update-editor-uis    #1629      +/-   ##
============================================================
+ Coverage                     20.69%   21.85%   +1.15%     
- Complexity                     2379     2431      +52     
============================================================
  Files                            46       48       +2     
  Lines                          8941     9153     +212     
============================================================
+ Hits                           1850     2000     +150     
- Misses                         7091     7153      +62     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@dkoo dkoo requested a review from miguelpeixe August 30, 2024 18:12
includes/class-send-list.php Outdated Show resolved Hide resolved
includes/class-send-list.php Outdated Show resolved Hide resolved
includes/class-send-list.php Show resolved Hide resolved
includes/class-send-list.php Outdated Show resolved Hide resolved
@dkoo dkoo requested a review from miguelpeixe August 30, 2024 20:01
Copy link
Member

@miguelpeixe miguelpeixe left a comment

Choose a reason for hiding this comment

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

Thank you for the revisions! Class and tests look great!

Let's get this in to review it in action 😎

// Cast value to the expected type.
settype( $value, $property['type'] );

$this->{ $key } = $value;
Copy link
Contributor

Choose a reason for hiding this comment

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

Setting the property directly into an undeclared object property has the downside of letting this prop public.

So I can still access $send_list->label which would skip our getter.

We could come up with some ideas to work around that, maybe using overloading somehow, but I think the easiest thing to do is to store all properties inside one private $config property, which will be an array holding all the properties...

makes sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I didn't realize that! 69e8232 refactors to use a single protected $config property instead of the separate undeclared properties. This also makes the to_array() method a bit simpler.

@miguelpeixe
Copy link
Member

@leogermani reviewed the same time as me 😄

/**
* Test matching by search term(s).
*/
public function test_match_by_search() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

When testing methods like this it is always desirable to test some reallly unhappy tests.

For example, what's the expected return if I pass NULL as one of the parameters? or an Object of any kind? or an integer, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great idea! f9bd959 adds some of these tests (as well as some missing handling for those weird cases!).

Copy link
Contributor

Choose a reason for hiding this comment

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

That's the beauty of writing tests :)

Copy link
Contributor

@leogermani leogermani left a comment

Choose a reason for hiding this comment

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

This is looking pretty good Derrick! Thanks for all the work building it!

I left only one comment regarding how we store the properties in the object. Other than that this is awesome!

@dkoo dkoo requested a review from leogermani August 30, 2024 23:11
@dkoo dkoo merged commit 00006cd into epic/update-editor-uis Sep 3, 2024
6 of 7 checks passed
@dkoo dkoo deleted the feat/send-lists branch September 3, 2024 15:32
dkoo added a commit that referenced this pull request Oct 14, 2024
* feat: make "Send To" UI autocomplete instead of dropdowns (#1577)

* feat: autocomplete "Send To" UI for CC + AC

* fix: sent post statuses for AC

* feat: autocomplete send-to UI for Mailchimp

* fix: support _n() contacts in AC + CC

* refactor: standardize "sent" status checks for all ESPs

* fix: function name for CC

* fix: set list_type for audiences

* fix: extra parentheses for AC

* feat: show suggestions on focus

* style: move external "Manage" links to button

* feat: design updates for autocomplete UI

* fix: send to summary

* fix: contact counts in send to summary

* fix: mailchimp and selected list styles

* fix: remove ID from AC segments

* fix: logic for contact count in send to summary

* fix: parse contact counts as int to avoid "1 contacts" output

* fix: translation strings for contact counts in summaries

* refactor: standardize use of renderSelectedSummary functions

* fix: translatable send-to summaries

* fix: allow 0 to be shown

* fix: grammar

* Update src/service-providers/active_campaign/ProviderSidebar.js

Co-authored-by: leogermani <leogermani@automattic.com>

* Update src/service-providers/active_campaign/ProviderSidebar.js

Co-authored-by: leogermani <leogermani@automattic.com>

* Update src/service-providers/constant_contact/ProviderSidebar.js

Co-authored-by: leogermani <leogermani@automattic.com>

* Update src/service-providers/constant_contact/ProviderSidebar.js

Co-authored-by: leogermani <leogermani@automattic.com>

* Update src/service-providers/mailchimp/ProviderSidebar.js

Co-authored-by: leogermani <leogermani@automattic.com>

* Update src/service-providers/mailchimp/ProviderSidebar.js

Co-authored-by: leogermani <leogermani@automattic.com>

* fix: translatable strings in SendTo component’s selected item label

---------

Co-authored-by: leogermani <leogermani@automattic.com>

* fix(editor): render notice on sync error (#1606)

* fix(mailchimp): improve sync error messages (#1619)

* fix(activecampaign): default message on request error (#1618)

* feat: cross-ESP send-lists

* refactor: move API namespace and permission callback to main class

* feat: support send lists in provider classes

* feat: refactor editor JS to use new standardized data

* fix: ensure Newsletters plugin blocks are grouped under Newspack category (#1630)

* feat: send list classes (#1629)

* feat: cross-ESP send-lists

* refactor: move API namespace and permission callback to main class

* refactor: feedback from code review

* fix: add missing get/set methods for count and parent_id

* refactor: more consistent naming for set_count method

* refactor: maintain exception but with WP_Error handling

* docs: add more explanation about Send_Lists

Co-authored-by: leogermani <leogermani@automattic.com>

* test: improve tests for matching methods

* refactor: set values on protected $config var

* docs: tweak wording of explanation

---------

Co-authored-by: leogermani <leogermani@automattic.com>

* feat: support send lists in ESP classes (#1631)

* feat: cross-ESP send-lists

* refactor: move API namespace and permission callback to main class

* feat: support send lists in provider classes

* fix: use getter methods for Send_List classes

* chore: clean up register_rest_route configs and permission callbacks

* fix: improve error handling for get_send_list methods

* fix: add error handling to send-lists API handler

* fix: return Send_List objects as arrays from provider methods

* fix: avoid unnecessary send-list API requests

* chore: remove unneeded methods

* fix: fatal error due to get_send_lists returning Send_List arrays instead of objects

* Revert "fix: fatal error due to get_send_lists returning Send_List arrays instead of objects"

This reverts commit 3ff1e65.

* fix: allow get_send_list methods to return either Send_List[] or arrays

* fix: correct type for supportedESPs fallback value

* fix(mc): subscriber send count in pre-send modal summary

* fix: formatting error

* fix: ensure supported_esps is an array, not an object

* fix: missed callable

* fix: cc error handling

* fix: better error handling for retrieve/sync request errors

* refactor: unify retrieve error handling across all ESPs

* refactor: throw error for missing MC creds, too

* test: update expected exception message

* refactor: consolidate ESP data getters into Redux store

* docs: update inline docs for Redux store

* fix: move SendTo to Sidebar component; avoid parallel retrieve requests

* refactor: always prefetch sublists on list select

* fix: account for missing selected list or sublist info

* fix: default sender/send-to for saved layouts

* fix: campaign_defaults meta field name

* fix: don't overwrite fetched lists/sublists info on retrieve

* fix: force release

* feat: add link to campaign in provider (#1661)

* fix: parse legacy layout defaults (#1663)

* fix: handle legacy layout defaults for MC

* fix: legacy layout defaults for AC + CC

* fix: senderName + senderEmail for AC

---------

Co-authored-by: leogermani <leogermani@automattic.com>
Co-authored-by: Miguel Peixe <miguel.peixe@a8c.com>
Co-authored-by: Miguel Peixe <miguel.peixe@automattic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Status] Approved Ready to merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants