refs https://github.com/TryGhost/Team/issues/1474
- The `default` concept will be replaced by the first newsletter based on the `sort_order`
- This removes the `default` value from the newsletter API
- This simplifies the design to make the api and datastructure more maintainable
refs https://github.com/TryGhost/Team/issues/1471
- This is a many-to-one relation so that many posts can be linked to a specific newsletter
- The `newsletters` table had to come first in the schema file so that it's initialized before the `posts` table (because of the foreign key)
- Updated the model to make sure the new field doesn't leak in the API for now
- This migration isn't using the `createAddColumnMigration` util because of a performance issue. In MySQL, adding/dropping a column without `algorithm=copy` uses the INPLACE algorithm which was too slow on big posts tables (~3 minutes for 10k posts). Switching to the COPY algorithm fixed the issue (~3 seconds for 10k posts).
- SQLite isn't using the codepath where we run a raw SQL query because `knex` is doing multiple queries to add/remove a column
refs https://github.com/TryGhost/Team/issues/1469
Currently, all new members get auto subscribed to the default newsletter. This change adds same behavior with multiple newsletters by auto subscribing all available newsletters on site for new members(If flag is enabled).
Note: In future, this will also take into consideration the `subscribe_on_signup` flag for a newsletter to filter which newsletters should a member be auto-subscribed.
- adds newsletters service for working with newsletter data
- bumps `@tryghost/members-api` package which handles default subscription
- adds new test fixture/data for newsletters
- The url service was moved from frontend to server some time ago but the tests were forgotten
- This is only being done now because in 5.0 major changes are happening and it'll be annoying if the
files move on that branch
refs https://github.com/TryGhost/Team/issues/1372
- Added tests for Stripe webhooks that cancel a subscription (paid and complimentary)
- Tests for manually adding a complimentary member, and removing it again (the 'new' way)
- Added tests for creating new members (paid, complimentary)
- Includes tests for the `stripe_customer_id` property when creating new members (this is broken, fixed by https://github.com/TryGhost/Members/pull/378#issuecomment-1070835800)
- Deduplicated some nock code for Stripe
- Improved event assertions and interference between multiple tests in the giant members test file (by asserting only for the affected member id instead of all events).
- This fits more closely, as this service is to so with rendering helpers and small parts
- Whereas we want to use "rendering" for things concerned with rendering pages
refs https://github.com/TryGhost/Team/issues/1469
- updates member model to add relation to newsletter via pivot table
- updates member api serializer to include newsletter data
- updates tests
refs: https://github.com/TryGhost/Ghost/commit/11867ab43
- These checks live in the wrong place. They are mostly a frontend thing
- The only server place they were used was slack and that was fixed in 11867ab43
- Moving these to the frontend they fit neatly into the frontend data service
- This is the only piece of server code that relies on the schema.checks, the rest are all frontend
- IMO this code should actually check for the post properties that the slack message needs
- OR it should switch based on the event type
- either way there's no need to have a shared util for this simple use case
- especially becaue it's confusing the use case for it and creating cross-coupling between server and frontend
- Some of the helpers inside the routing service would be better suited to their own service
- These two helpers fetchData and entryLookup talk to the API to get data & so make a decent start for a data service
- The data service would be the single point of contact with the API for the frontend
- Doing this now cos I'm moving some files around ahead of deleting things for 5.0
refs https://github.com/TryGhost/Team/issues/1469
With multiple newsletters, members will now be able to subscribe to one or more newsletters on the site. Previously, the subscription to default newsletter for a member was controlled via a single boolean `subscribed` column on the member table.
This change allows mapping multiple newsletters to a member via new pivot table that stores relation between a member and newsletter.
- adds new `members_newsletters` pivot table
- update tests
- Updated express-test to latest version with new expectEmptyBody assertion
- Updated all the tests that used matchBodySnapshot for an empty body to use expectEmptyBody instead
- Updated all the snapshots that were affected manually, and verified running the tests works as expected
refs https://github.com/TryGhost/Team/issues/1463
- Allow admins to perform all newsletter operations
- We can adjust and be more permissive in the future if needed
- Added the tests back as permissions are configured correctly now
refs TryGhost/Team#1458
refs TryGhost/Team#1459
refs TryGhost/Team#1372
- Added a new stats service, which is divided into several categories. Currently only the 'members' category for member related stats.
- When there are missing or corrupt members status events in the DB, the totals returned by the old member stats endpoint (`/members/stats/count`) were wrong. This is fixed in the new service by counting in reverse order and starting with the actual totals.
- New Stats API, with the new `/stats/members/count-history` endpoint.
- This new endpoint also returns the paid deltas -> dashboard 5.0 will show subscribed and canceled paid members for each day
- Includes tests for the new stats service and endpoint
refs https://github.com/TryGhost/Team/issues/1463
- This enables listing, creating and editing newsletters
- The tests are commented out as the permissions will be added in a follow-up commit
- Snippets are are one of the most recently implemented full e2e features
- https://github.com/TryGhost/Ghost/commit/13f653a12 updated the serialier pattern
- This updates the tests so _everything_ is shiny and new
refs: https://github.com/TryGhost/Toolbox/issues/245
- The default behaviour of a serializer is to call a mapper for each object
- Instead of all the boilerplate code we had in the snippets serializer, all we need is a single mapper function
- Added tests for the mapper function as well
refs https://github.com/TryGhost/Team/issues/1433
- The `default` property stores whether a newsletter is set as default by the admin
- The `status` property stores whether a newsletter is archived or not
- The `recipient_filter` property is only storing whether a newsletter is "paid-only" or not for now, although it can be expanded to more specific filters in the future
- The `subscribe_on_signup` property stores whether a new member should be automatically signed up to the newsletter
- The `sort_order` property enables displaying the newsletter list in an order chosen by the admins
refs: https://github.com/TryGhost/Toolbox/issues/245
- .all methods are fallback serializers not to be run as well as a custom serializer
- The default serializer is also a fallback
- The "All" file with before and after are global hooks that _always_ get run as well as other serializers
- There's a lot of room for further improvement here especially with naming but this logic makes more sense
for the usecases AND doesn't affect v2 & v3 etc. We can do another pass after 5.0
- Allows mocking lib/common/events - stubs event.emit
- Means we can check that events fired, but their sideeffects won't happen, useful for things like bulk email
- I also reorganised the mock manager file to group related functions together
refs: https://github.com/TryGhost/Team/issues/1446
- changed mail API tests to use the new e2e test framework
- added the missing retry test - which has the wrong response format :(
mail
refs https://github.com/TryGhost/Toolbox/issues/213
- `better-sqlite3` doesn't like multiple queries in the same statement
so we can make the change here to split them up ahead of the switch
refs: https://github.com/TryGhost/Ghost/commit/e68cb8b31
- I found that some of the places we use rewire are totally unnecessary
- Rewire seems to mess with coverage sometimes
- It's also a code smell in general so I've ripped it out where possible
refs: 0ef5a5c97a
- As per the previous commit, our mixed filename casing inadvertently resulted in a bug
- The casing in the codebase is meant to be kebab-case always, so fixing this everywhere that's relevant to the API whilst there's a good reason
refs: https://github.com/TryGhost/Toolbox/issues/245
refs: https://github.com/TryGhost/Team/issues/1360
- As a result of my changes in https://github.com/TryGhost/Ghost/commit/3bd4d098 the members connect endpoint had started returning JSON
- This is because the members connect endpoint relied on the old default behaviour of the serializer being to return no response, whereas now it does our default JSON response format
- I had written a tool to iterate over all endpoints and ensure that they all had explicit serializers before changing the default behaviour, but it missed this endpoint due to the snake case naming
- I have double checked and this was the only missed endpoint, the only other one was member_signin_urls.permissions but that was not a true endpoint and was removed in https://github.com/TryGhost/Ghost/commit/202696382
- Note: the snapshot file for this test was generated from running the test against https://github.com/TryGhost/Ghost/commit/e6b92aed9 - one commit before I added the new default behaviour.
- Without the new serializer this test fails on main
- With the new serialzier, this test passes again, showing the response format has gone back to what we expect
refs https://github.com/TryGhost/Toolbox/issues/241
- The `engines.ghost-api` property has been deprecated and the support for it will be dropped in Ghost v5 due to versionless nature of the Content API.
- When uploading a new theme or activating existing one that uses ghost-api in it's config a warning will be shown to the user
refs: https://github.com/TryGhost/Toolbox/issues/245
- we don't need this serializer because the default serializer will call the tags mapper
- for now I've changed, rather than removed the tag serializer test as this shows default works the same!
refs: https://github.com/TryGhost/Toolbox/issues/245
- There's no need for a mapper or serializer as labels uses the default behaviour
- Added a full suite of tests, consolidating from regression and using the new framework to prove nothing is broken
- settings cache was appearing as untested because we use rewire!
- rewire was totally unnecessary in this case, so I removed it
- updated to 100% test coverage whilst there, including removing one unreachable branch
- commented some undesirable behaviour I found whilst trying to reach all branches
- I don't want to change the behaviour to return false correctly without having a reason beyond improving coverage
refs: https://github.com/TryGhost/Toolbox/issues/245
- Added a serializer called default to the canary API
- Ideally, this would be part of the shared framework, but this would change v2/v3 and we're about to get rid of them
- Therefore, we change just canary for now, and we can refactor again later.
- Added wiring to handler that uses the default serializer, if there is a default, and isn't an explicit serializer for the endpoint
- Removed the invites serializer, so that one endpoint now uses the default
Note: previous commits have added explicit serializers to every endpoint, this is the first step towards paring
that back so that we have less serializers overall, not more!
refs: https://github.com/TryGhost/Toolbox/issues/245
- Upload, updateMembersEmail, validateMembersEmailUpdate & disconnectStripeConnectIntegration were all missing serializers
- Upload is an as-is response, same as download
- updateMembersEmail, validateMembersEmailUpdate & disconnectStripeConnectIntegration are all passthroughs with no response
- With the upcoming refactor we want to have all the serializers defined explicitly
- This will allow us to change the default behaviour
- Updated the file based tests to prove the body doesn't change
- Tests were added to cover updateMembersEmail, validateMembersEmailUpdate & disconnectStripeConnectIntegration in 68c1bc0285
refs: https://github.com/TryGhost/Toolbox/issues/245
- sendTestEmail was missing a serializer because it's deliberately a passthrough
- With the upcoming refactor we want to have all the serializers defined explicitly
- This will allow us to change the default behaviour
- Updated the tests to prove the body doesn't change
refs: https://github.com/TryGhost/Toolbox/issues/245
- The destroy endpoint was missing a serializer
- Instead of adding one, I've refactored to use an all method that's a passthrough
- Updated the tests to use the same pattern as others to make it clearer this is tested
refs: https://github.com/TryGhost/Toolbox/issues/245
- The destroy endpoint was missing a serializer
- As this serializer uses the same createSerializer pattern as members, I've copied the passthrough from members into here
- This ensures the behaviour will stay the same when the default behaviour changes
- Updated the tests to prove the body doesn't change
refs: https://github.com/TryGhost/Toolbox/issues/245
- The destroy endpoint was missing a serializer
- Instead of adding one, we've refactored to use the standard structure for this serializer
- Updated the tests to prove the body doesn't change
refs: https://github.com/TryGhost/Toolbox/issues/245
- There was only a serializer in place for redirects.download.
- Upload was falling through, which means nothing happens by default atm
- We want to change this default, so I'm making sure all our routes have serializers declared and tests
- Updated the tests and checked the behaviour was the same before and after:
- We can't use our new framework here yet because it doesn't support uploads or downloads
- Instead, just add simple matching for the body of the responses
refs https://github.com/TryGhost/Toolbox/issues/241
- The `engines.ghost-api` property has been deprecated and the support for it will be dropped in Ghost v5 due to versionless nature of the Content API.
- When uploading a new theme or activating existing one that uses ghost-api in it's config a warning will be shown to the user