diff --git a/.gitignore b/.gitignore index 52c8085..4434dac 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .DS_Store +.phpunit.result.cache /vendor /composer.lock diff --git a/README.md b/README.md index 47f5d63..4ca2d9b 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ You can also exclude single routes, or route groups with wildcards. This will ov ], ``` -### Dynamically adding routes +### Dynamic Routes You may add URLs dynamically by providing a closure that returns an array to the `addUrls` method. @@ -81,6 +81,16 @@ class AppServiceProvider extends Provider } ``` +### Pagination Routes + +Wherever pagination is detected in your antlers templates (eg. if you use the `paginate` param on the `collection` tag), multiple pages will automatically be generated with `/articles/page/2` style urls. + +You may configure a custom routing style in `config/statamic/ssg.php`: + +```php +'pagination_route' => '{url}/{page_name}/{page_number}', +``` + ## Post-generation callback diff --git a/config/ssg.php b/config/ssg.php index e3436ab..ae331a4 100644 --- a/config/ssg.php +++ b/config/ssg.php @@ -73,6 +73,19 @@ // ], + /* + |-------------------------------------------------------------------------- + | Pagination Route + |-------------------------------------------------------------------------- + | + | Here you may define how paginated entries are routed. This will take + | effect wherever pagination is detected in your antlers templates, + | like if you use the `paginate` param on the `collection` tag. + | + */ + + 'pagination_route' => '{url}/{page_name}/{page_number}', + /* |-------------------------------------------------------------------------- | Glide diff --git a/phpunit.xml b/phpunit.xml index b2b92bb..bfc27ff 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -18,5 +18,7 @@ + + diff --git a/src/LengthAwarePaginator.php b/src/LengthAwarePaginator.php new file mode 100644 index 0000000..edbdb45 --- /dev/null +++ b/src/LengthAwarePaginator.php @@ -0,0 +1,39 @@ +path(), $this->getPageName(), $page); + + if (Str::contains($this->path(), '?') || count($this->query)) { + $url .= '?'.Arr::query($this->query); + } + + return $url.$this->buildFragment(); + } + + public static function generatePaginatedUrl($url, $pageName, $pageNumber) + { + $route = config('statamic.ssg.pagination_route'); + + $url = str_replace('{url}', $url, $route); + + $url = str_replace('{page_name}', $pageName, $url); + + $url = str_replace('{page_number}', $pageNumber, $url); + + return URL::makeRelative($url); + } +} diff --git a/src/Page.php b/src/Page.php index 6c3ff1d..1145d1f 100644 --- a/src/Page.php +++ b/src/Page.php @@ -6,12 +6,15 @@ use Illuminate\Filesystem\Filesystem; use Illuminate\Http\Exceptions\HttpResponseException; use Illuminate\Http\RedirectResponse; +use Statamic\Facades\Blink; class Page { protected $files; protected $config; protected $content; + protected $paginationPageName; + protected $paginationCurrentPage; public function __construct(Filesystem $files, array $config, $content) { @@ -33,14 +36,24 @@ public function isGeneratable() public function generate($request) { try { - return $this->write($request); + $generatedPage = $this->write($request); } catch (Exception $e) { throw new NotGeneratedException($this, $e); } + + if ($paginator = $this->detectPaginator($request)) { + $this->writePaginatedPages($request, $paginator); + } + + return $generatedPage; } protected function write($request) { + if ($this->paginationPageName) { + $request->merge([$this->paginationPageName => $this->paginationCurrentPage]); + } + try { $response = $this->content->toResponse($request); } catch (HttpResponseException $e) { @@ -59,6 +72,23 @@ protected function write($request) return new GeneratedPage($this, $response); } + protected function writePaginatedPages($request, $paginator) + { + collect(range(1, $paginator->lastPage()))->each(function ($pageNumber) use ($request) { + $page = clone $this; + + try { + $page + ->setPaginationCurrentPage($pageNumber) + ->write($request); + } catch (Exception $e) { + throw new NotGeneratedException($page, $e); + } + }); + + $this->clearPaginator($request); + } + public function directory() { return dirname($this->path()); @@ -85,7 +115,17 @@ public function path() public function url() { - return $this->content->urlWithoutRedirect(); + $url = $this->content->urlWithoutRedirect(); + + if ($this->paginationCurrentPage) { + $url = LengthAwarePaginator::generatePaginatedUrl( + $url, + $this->paginationPageName, + $this->paginationCurrentPage + ); + } + + return $url; } public function site() @@ -97,4 +137,31 @@ public function is404() { return $this->url() === '/404'; } + + public function setPaginationCurrentPage($currentPage) + { + $this->paginationCurrentPage = $currentPage; + + return $this; + } + + protected function detectPaginator($request) + { + if ($paginator = Blink::get('tag-paginator')) { + $this->paginationPageName = $paginator->getPageName(); + } + + $this->clearPaginator($request); + + return $paginator; + } + + protected function clearPaginator($request) + { + Blink::forget('tag-paginator'); + + if ($this->paginationPageName) { + $request->forget($this->paginationPageName); + } + } } diff --git a/src/Request.php b/src/Request.php index 5624f33..e785114 100644 --- a/src/Request.php +++ b/src/Request.php @@ -61,4 +61,11 @@ public function path() return ltrim($path, '/'); } + + public function forget(string $inputKey) + { + $this->getInputSource()->remove($inputKey); + + return $this; + } } diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 48d7e12..ec883c0 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -4,13 +4,16 @@ use Illuminate\Support\ServiceProvider as LaravelServiceProvider; use Spatie\Fork\Fork; +use Statamic\Extensions\Pagination\LengthAwarePaginator as StatamicLengthAwarePaginator; class ServiceProvider extends LaravelServiceProvider { public function register() { + $this->app->bind('fork-installed', fn () => class_exists(Fork::class)); + $this->app->bind(Tasks::class, function ($app) { - return $app->runningInConsole() && class_exists(Fork::class) + return $app->runningInConsole() && $app['fork-installed'] ? new ConcurrentTasks(new Fork) : new ConsecutiveTasks; }); @@ -33,5 +36,17 @@ public function boot() Commands\StaticSiteServe::class, ]); } + + if ($this->app->runningInConsole()) { + $this->app->extend(StatamicLengthAwarePaginator::class, function ($paginator) { + return $this->app->makeWith(LengthAwarePaginator::class, [ + 'items' => $paginator->getCollection(), + 'total' => $paginator->total(), + 'perPage' => $paginator->perPage(), + 'currentPage' => $paginator->currentPage(), + 'options' => $paginator->getOptions(), + ]); + }); + } } } diff --git a/tests/Concerns/RunsGeneratorCommand.php b/tests/Concerns/RunsGeneratorCommand.php new file mode 100644 index 0000000..afe5ebe --- /dev/null +++ b/tests/Concerns/RunsGeneratorCommand.php @@ -0,0 +1,77 @@ +destination = storage_path('app/static'); + + $this->cleanUpDestination(); + } + + public function tearDown(): void + { + $this->cleanUpDestination(); + + parent::tearDown(); + } + + protected function generate() + { + $this->assertFalse($this->files->exists($this->destination)); + + $this + ->artisan('statamic:ssg:generate') + ->doesntExpectOutputToContain('pages not generated'); + + $this->assertTrue($this->files->exists($this->destination)); + + return $this->getGeneratedFilesAtPath($this->destination); + } + + protected function relativePath($path) + { + return str_replace(Path::tidy($this->destination.'/'), '', Path::tidy($path)); + } + + protected function destinationPath($path) + { + return Path::tidy($this->destination.'/'.$path); + } + + protected function getGeneratedFilesAtPath($path) + { + return collect($this->files->allFiles($path)) + ->mapWithKeys(fn ($file) => [$this->relativePath($file->getPathname()) => $file->getContents()]) + ->all(); + } + + protected function cleanUpDestination($destination = null) + { + $destination ??= $this->destination; + + if ($this->files->exists($destination)) { + $this->files->deleteDirectory($destination); + } + } + + protected function assertStringContainsStrings($needleStrings, $haystackString) + { + foreach ($needleStrings as $string) { + $this->assertStringContainsString($string, $haystackString); + } + } + + protected function assertStringNotContainsStrings($needleStrings, $haystackString) + { + foreach ($needleStrings as $string) { + $this->assertStringNotContainsString($string, $haystackString); + } + } +} diff --git a/tests/Fixtures/resources/views/articles/index.antlers.html b/tests/Fixtures/resources/views/articles/index.antlers.html new file mode 100644 index 0000000..bdc4e10 --- /dev/null +++ b/tests/Fixtures/resources/views/articles/index.antlers.html @@ -0,0 +1,4 @@ +

Articles Index Page Title

+{{ collection:articles sort="date:asc" }} + {{ title }} +{{ /collection:articles }} diff --git a/tests/Fixtures/resources/views/articles/show.antlers.html b/tests/Fixtures/resources/views/articles/show.antlers.html new file mode 100644 index 0000000..e941cd1 --- /dev/null +++ b/tests/Fixtures/resources/views/articles/show.antlers.html @@ -0,0 +1,2 @@ +

Article Title: {{ title }}

+

Content: {{ content }}

diff --git a/tests/Fixtures/resources/views/default.antlers.html b/tests/Fixtures/resources/views/default.antlers.html new file mode 100644 index 0000000..924fad5 --- /dev/null +++ b/tests/Fixtures/resources/views/default.antlers.html @@ -0,0 +1,2 @@ +

Page Title: {{ title }}

+

Content: {{ content }}

diff --git a/tests/Fixtures/resources/views/errors/404.antlers.html b/tests/Fixtures/resources/views/errors/404.antlers.html new file mode 100644 index 0000000..d78be50 --- /dev/null +++ b/tests/Fixtures/resources/views/errors/404.antlers.html @@ -0,0 +1 @@ +

404!

diff --git a/tests/Fixtures/resources/views/layout.antlers.html b/tests/Fixtures/resources/views/layout.antlers.html new file mode 100644 index 0000000..82b8e00 --- /dev/null +++ b/tests/Fixtures/resources/views/layout.antlers.html @@ -0,0 +1,2 @@ +{{ seo_pro:meta }} +{{ template_content }} diff --git a/tests/Fixtures/site-localized/content/collections/articles.yaml b/tests/Fixtures/site-localized/content/collections/articles.yaml new file mode 100644 index 0000000..d91eadc --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles.yaml @@ -0,0 +1,16 @@ +title: Articles +sites: + - default + - french +route: + default: 'articles/{slug}' + french: 'le-articles/{slug}' +template: articles.show +mount: b9e4bfe3-9c12-4553-b7ef-f43c22ffaa63 +taxonomies: + - topics +revisions: false +date: true +date_behavior: + past: public + future: private diff --git a/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-01.one.md b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-01.one.md new file mode 100644 index 0000000..9792983 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-01.one.md @@ -0,0 +1,4 @@ +--- +id: a356f052-06a3-4f37-8376-2f136fe973c3 +title: One +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-02.two.md b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-02.two.md new file mode 100644 index 0000000..107524b --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-02.two.md @@ -0,0 +1,4 @@ +--- +id: ca648856-ff12-407d-a523-72074f5997e1 +title: Two +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-03.three.md b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-03.three.md new file mode 100644 index 0000000..059a10f --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-03.three.md @@ -0,0 +1,4 @@ +--- +id: 312dff5e-4d4e-44bd-ac47-80ef58278675 +title: Three +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-04.four.md b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-04.four.md new file mode 100644 index 0000000..b3d4282 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-04.four.md @@ -0,0 +1,4 @@ +--- +id: d813ea6f-a637-4c6b-a724-c9e5f70e23de +title: Four +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-05.five.md b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-05.five.md new file mode 100644 index 0000000..38d8f24 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-05.five.md @@ -0,0 +1,4 @@ +--- +id: 3a2e2f92-f93e-481d-b120-c63ff09c1775 +title: Five +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-06.six.md b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-06.six.md new file mode 100644 index 0000000..d544613 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-06.six.md @@ -0,0 +1,4 @@ +--- +id: c72306d0-b6ae-4f3a-88eb-6c01d5a83c0d +title: Six +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-07.seven.md b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-07.seven.md new file mode 100644 index 0000000..a5c56a5 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-07.seven.md @@ -0,0 +1,4 @@ +--- +id: 6614e8af-4c11-4790-a47e-ebb6b685851d +title: Seven +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-08.eight.md b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-08.eight.md new file mode 100644 index 0000000..7d6fff9 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/default/2023-07-08.eight.md @@ -0,0 +1,4 @@ +--- +id: 219487f7-3390-444b-814f-7fc4dc412d6c +title: Eight +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-01.le-one.md b/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-01.le-one.md new file mode 100644 index 0000000..6417a75 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-01.le-one.md @@ -0,0 +1,5 @@ +--- +id: a356f052-06a3-4f37-8376-2f136fe973c3-french +origin: a356f052-06a3-4f37-8376-2f136fe973c3 +title: Le One +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-02.le-two.md b/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-02.le-two.md new file mode 100644 index 0000000..703c90c --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-02.le-two.md @@ -0,0 +1,5 @@ +--- +id: ca648856-ff12-407d-a523-72074f5997e1-french +origin: ca648856-ff12-407d-a523-72074f5997e1 +title: Le Two +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-03.le-three.md b/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-03.le-three.md new file mode 100644 index 0000000..3edbd1f --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-03.le-three.md @@ -0,0 +1,5 @@ +--- +id: 312dff5e-4d4e-44bd-ac47-80ef58278675-french +origin: 312dff5e-4d4e-44bd-ac47-80ef58278675 +title: Le Three +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-04.le-four.md b/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-04.le-four.md new file mode 100644 index 0000000..df73ca4 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-04.le-four.md @@ -0,0 +1,5 @@ +--- +id: d813ea6f-a637-4c6b-a724-c9e5f70e23de-french +origin: d813ea6f-a637-4c6b-a724-c9e5f70e23de +title: Le Four +--- diff --git a/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-05.le-five.md b/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-05.le-five.md new file mode 100644 index 0000000..37fbe5d --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/articles/french/2023-07-05.le-five.md @@ -0,0 +1,5 @@ +--- +id: 3a2e2f92-f93e-481d-b120-c63ff09c1775-french +origin: 3a2e2f92-f93e-481d-b120-c63ff09c1775 +title: Le Five +--- diff --git a/tests/Fixtures/site-localized/content/collections/pages.yaml b/tests/Fixtures/site-localized/content/collections/pages.yaml new file mode 100644 index 0000000..1d99167 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/pages.yaml @@ -0,0 +1,8 @@ +title: Pages +sites: + - default + - french +revisions: false +route: '{parent_uri}/{slug}' +structure: + root: true diff --git a/tests/Fixtures/site-localized/content/collections/pages/default/about.md b/tests/Fixtures/site-localized/content/collections/pages/default/about.md new file mode 100644 index 0000000..c556171 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/pages/default/about.md @@ -0,0 +1,7 @@ +--- +title: About +updated_by: 96300192-873c-4615-b992-157508a8d7c5 +updated_at: 1579284102 +id: 62136fa2-9e5c-4c38-a894-a2753f02f5ff +--- +I'm just a kid living in the 90's, writing articles in his secret public journal wonder if someday, somewhere in the future, they will be read by someone. diff --git a/tests/Fixtures/site-localized/content/collections/pages/default/articles.md b/tests/Fixtures/site-localized/content/collections/pages/default/articles.md new file mode 100644 index 0000000..9f07676 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/pages/default/articles.md @@ -0,0 +1,8 @@ +--- +title: Articles +template: articles.index +updated_by: 96300192-873c-4615-b992-157508a8d7c5 +updated_at: 1579283552 +id: b9e4bfe3-9c12-4553-b7ef-f43c22ffaa63 +--- +These are my various writings. Some might say they are cool. \ No newline at end of file diff --git a/tests/Fixtures/site-localized/content/collections/pages/default/home.md b/tests/Fixtures/site-localized/content/collections/pages/default/home.md new file mode 100644 index 0000000..9f7d027 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/pages/default/home.md @@ -0,0 +1,8 @@ +--- +title: Home +subtitle: 'I see pride. I see power.' +updated_by: b6c037ad-5bcc-41a8-a455-9ab54573f689 +updated_at: 1606223924 +id: home +--- +I see a bad-ass mother. diff --git a/tests/Fixtures/site-localized/content/collections/pages/default/topics.md b/tests/Fixtures/site-localized/content/collections/pages/default/topics.md new file mode 100644 index 0000000..ec52c20 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/pages/default/topics.md @@ -0,0 +1,6 @@ +--- +title: Topics +updated_by: ea0c21bd-9703-4bb1-9fed-58ec0e129dd7 +updated_at: 1579534416 +id: f5a53468-017e-4725-b5b6-a745df7e94cb +--- diff --git a/tests/Fixtures/site-localized/content/collections/pages/french/le-about.md b/tests/Fixtures/site-localized/content/collections/pages/french/le-about.md new file mode 100644 index 0000000..9ba10f6 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/pages/french/le-about.md @@ -0,0 +1,8 @@ +--- +title: Le About +updated_by: 96300192-873c-4615-b992-157508a8d7c5 +updated_at: 1579284102 +id: 62136fa2-9e5c-4c38-a894-a2753f02f5ff-french +origin: 62136fa2-9e5c-4c38-a894-a2753f02f5ff +--- +I'm just a kid living in the 90's, writing articles in his secret public journal wonder if someday, somewhere in the future, they will be read by someone. diff --git a/tests/Fixtures/site-localized/content/collections/pages/french/le-articles.md b/tests/Fixtures/site-localized/content/collections/pages/french/le-articles.md new file mode 100644 index 0000000..9d2cff1 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/pages/french/le-articles.md @@ -0,0 +1,9 @@ +--- +title: Le Articles +template: articles.index +updated_by: 96300192-873c-4615-b992-157508a8d7c5 +updated_at: 1579283552 +id: b9e4bfe3-9c12-4553-b7ef-f43c22ffaa63-french +origin: b9e4bfe3-9c12-4553-b7ef-f43c22ffaa63 +--- +These are my various writings. Some might say they are cool. diff --git a/tests/Fixtures/site-localized/content/collections/pages/french/le-home.md b/tests/Fixtures/site-localized/content/collections/pages/french/le-home.md new file mode 100644 index 0000000..4251224 --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/pages/french/le-home.md @@ -0,0 +1,9 @@ +--- +title: Le Home +subtitle: 'I see pride. I see power.' +updated_by: b6c037ad-5bcc-41a8-a455-9ab54573f689 +updated_at: 1606223924 +id: home-french +origin: home +--- +I see a bad-ass mother. diff --git a/tests/Fixtures/site-localized/content/collections/pages/french/le-topics.md b/tests/Fixtures/site-localized/content/collections/pages/french/le-topics.md new file mode 100644 index 0000000..00d220e --- /dev/null +++ b/tests/Fixtures/site-localized/content/collections/pages/french/le-topics.md @@ -0,0 +1,7 @@ +--- +title: Le Topics +updated_by: ea0c21bd-9703-4bb1-9fed-58ec0e129dd7 +updated_at: 1579534416 +id: f5a53468-017e-4725-b5b6-a745df7e94cb-french +origin: f5a53468-017e-4725-b5b6-a745df7e94cb +--- diff --git a/tests/Fixtures/site-localized/content/trees/collections/default/pages.yaml b/tests/Fixtures/site-localized/content/trees/collections/default/pages.yaml new file mode 100644 index 0000000..da59780 --- /dev/null +++ b/tests/Fixtures/site-localized/content/trees/collections/default/pages.yaml @@ -0,0 +1,3 @@ +tree: + - + entry: home diff --git a/tests/Fixtures/site-localized/content/trees/collections/french/pages.yaml b/tests/Fixtures/site-localized/content/trees/collections/french/pages.yaml new file mode 100644 index 0000000..0a07f75 --- /dev/null +++ b/tests/Fixtures/site-localized/content/trees/collections/french/pages.yaml @@ -0,0 +1,3 @@ +tree: + - + entry: home-french diff --git a/tests/Fixtures/site/content/collections/articles.yaml b/tests/Fixtures/site/content/collections/articles.yaml new file mode 100644 index 0000000..3a271d0 --- /dev/null +++ b/tests/Fixtures/site/content/collections/articles.yaml @@ -0,0 +1,11 @@ +title: Articles +route: 'articles/{slug}' +template: articles.show +mount: b9e4bfe3-9c12-4553-b7ef-f43c22ffaa63 +taxonomies: + - topics +revisions: false +date: true +date_behavior: + past: public + future: private diff --git a/tests/Fixtures/site/content/collections/articles/2023-07-01.one.md b/tests/Fixtures/site/content/collections/articles/2023-07-01.one.md new file mode 100644 index 0000000..9792983 --- /dev/null +++ b/tests/Fixtures/site/content/collections/articles/2023-07-01.one.md @@ -0,0 +1,4 @@ +--- +id: a356f052-06a3-4f37-8376-2f136fe973c3 +title: One +--- diff --git a/tests/Fixtures/site/content/collections/articles/2023-07-02.two.md b/tests/Fixtures/site/content/collections/articles/2023-07-02.two.md new file mode 100644 index 0000000..107524b --- /dev/null +++ b/tests/Fixtures/site/content/collections/articles/2023-07-02.two.md @@ -0,0 +1,4 @@ +--- +id: ca648856-ff12-407d-a523-72074f5997e1 +title: Two +--- diff --git a/tests/Fixtures/site/content/collections/articles/2023-07-03.three.md b/tests/Fixtures/site/content/collections/articles/2023-07-03.three.md new file mode 100644 index 0000000..059a10f --- /dev/null +++ b/tests/Fixtures/site/content/collections/articles/2023-07-03.three.md @@ -0,0 +1,4 @@ +--- +id: 312dff5e-4d4e-44bd-ac47-80ef58278675 +title: Three +--- diff --git a/tests/Fixtures/site/content/collections/articles/2023-07-04.four.md b/tests/Fixtures/site/content/collections/articles/2023-07-04.four.md new file mode 100644 index 0000000..b3d4282 --- /dev/null +++ b/tests/Fixtures/site/content/collections/articles/2023-07-04.four.md @@ -0,0 +1,4 @@ +--- +id: d813ea6f-a637-4c6b-a724-c9e5f70e23de +title: Four +--- diff --git a/tests/Fixtures/site/content/collections/articles/2023-07-05.five.md b/tests/Fixtures/site/content/collections/articles/2023-07-05.five.md new file mode 100644 index 0000000..38d8f24 --- /dev/null +++ b/tests/Fixtures/site/content/collections/articles/2023-07-05.five.md @@ -0,0 +1,4 @@ +--- +id: 3a2e2f92-f93e-481d-b120-c63ff09c1775 +title: Five +--- diff --git a/tests/Fixtures/site/content/collections/articles/2023-07-06.six.md b/tests/Fixtures/site/content/collections/articles/2023-07-06.six.md new file mode 100644 index 0000000..d544613 --- /dev/null +++ b/tests/Fixtures/site/content/collections/articles/2023-07-06.six.md @@ -0,0 +1,4 @@ +--- +id: c72306d0-b6ae-4f3a-88eb-6c01d5a83c0d +title: Six +--- diff --git a/tests/Fixtures/site/content/collections/articles/2023-07-07.seven.md b/tests/Fixtures/site/content/collections/articles/2023-07-07.seven.md new file mode 100644 index 0000000..a5c56a5 --- /dev/null +++ b/tests/Fixtures/site/content/collections/articles/2023-07-07.seven.md @@ -0,0 +1,4 @@ +--- +id: 6614e8af-4c11-4790-a47e-ebb6b685851d +title: Seven +--- diff --git a/tests/Fixtures/site/content/collections/articles/2023-07-08.eight.md b/tests/Fixtures/site/content/collections/articles/2023-07-08.eight.md new file mode 100644 index 0000000..7d6fff9 --- /dev/null +++ b/tests/Fixtures/site/content/collections/articles/2023-07-08.eight.md @@ -0,0 +1,4 @@ +--- +id: 219487f7-3390-444b-814f-7fc4dc412d6c +title: Eight +--- diff --git a/tests/Fixtures/site/content/collections/pages.yaml b/tests/Fixtures/site/content/collections/pages.yaml new file mode 100644 index 0000000..ffa599c --- /dev/null +++ b/tests/Fixtures/site/content/collections/pages.yaml @@ -0,0 +1,5 @@ +title: Pages +revisions: false +route: '{parent_uri}/{slug}' +structure: + root: true diff --git a/tests/Fixtures/site/content/collections/pages/about.md b/tests/Fixtures/site/content/collections/pages/about.md new file mode 100644 index 0000000..c556171 --- /dev/null +++ b/tests/Fixtures/site/content/collections/pages/about.md @@ -0,0 +1,7 @@ +--- +title: About +updated_by: 96300192-873c-4615-b992-157508a8d7c5 +updated_at: 1579284102 +id: 62136fa2-9e5c-4c38-a894-a2753f02f5ff +--- +I'm just a kid living in the 90's, writing articles in his secret public journal wonder if someday, somewhere in the future, they will be read by someone. diff --git a/tests/Fixtures/site/content/collections/pages/articles.md b/tests/Fixtures/site/content/collections/pages/articles.md new file mode 100644 index 0000000..9f07676 --- /dev/null +++ b/tests/Fixtures/site/content/collections/pages/articles.md @@ -0,0 +1,8 @@ +--- +title: Articles +template: articles.index +updated_by: 96300192-873c-4615-b992-157508a8d7c5 +updated_at: 1579283552 +id: b9e4bfe3-9c12-4553-b7ef-f43c22ffaa63 +--- +These are my various writings. Some might say they are cool. \ No newline at end of file diff --git a/tests/Fixtures/site/content/collections/pages/home.md b/tests/Fixtures/site/content/collections/pages/home.md new file mode 100644 index 0000000..9f7d027 --- /dev/null +++ b/tests/Fixtures/site/content/collections/pages/home.md @@ -0,0 +1,8 @@ +--- +title: Home +subtitle: 'I see pride. I see power.' +updated_by: b6c037ad-5bcc-41a8-a455-9ab54573f689 +updated_at: 1606223924 +id: home +--- +I see a bad-ass mother. diff --git a/tests/Fixtures/site/content/collections/pages/topics.md b/tests/Fixtures/site/content/collections/pages/topics.md new file mode 100644 index 0000000..ec52c20 --- /dev/null +++ b/tests/Fixtures/site/content/collections/pages/topics.md @@ -0,0 +1,6 @@ +--- +title: Topics +updated_by: ea0c21bd-9703-4bb1-9fed-58ec0e129dd7 +updated_at: 1579534416 +id: f5a53468-017e-4725-b5b6-a745df7e94cb +--- diff --git a/tests/Fixtures/site/content/trees/collections/pages.yaml b/tests/Fixtures/site/content/trees/collections/pages.yaml new file mode 100644 index 0000000..da59780 --- /dev/null +++ b/tests/Fixtures/site/content/trees/collections/pages.yaml @@ -0,0 +1,3 @@ +tree: + - + entry: home diff --git a/tests/GenerateTest.php b/tests/GenerateTest.php new file mode 100644 index 0000000..1f8bd02 --- /dev/null +++ b/tests/GenerateTest.php @@ -0,0 +1,234 @@ +generate(); + + $expectedFiles = [ + '404.html', + 'index.html', + 'about/index.html', + 'topics/index.html', + 'articles/index.html', + 'articles/one/index.html', + 'articles/two/index.html', + 'articles/three/index.html', + 'articles/four/index.html', + 'articles/five/index.html', + 'articles/six/index.html', + 'articles/seven/index.html', + 'articles/eight/index.html', + ]; + + $this->assertEqualsCanonicalizing($expectedFiles, array_keys($files)); + + $this->assertStringContainsString('

404!

', $files['404.html']); + + $this->assertStringContainsString('

Page Title: Home

', $files['index.html']); + $this->assertStringContainsString('

Page Title: About

', $files['about/index.html']); + $this->assertStringContainsString('

Page Title: Topics

', $files['topics/index.html']); + + $this->assertStringContainsString('

Articles Index Page Title

', $index = $files['articles/index.html']); + $this->assertStringContainsString('One', $index); + $this->assertStringContainsString('Two', $index); + $this->assertStringContainsString('Three', $index); + $this->assertStringContainsString('Four', $index); + $this->assertStringContainsString('Five', $index); + $this->assertStringContainsString('Six', $index); + $this->assertStringContainsString('Seven', $index); + $this->assertStringContainsString('Eight', $index); + + $this->assertStringContainsString('

Article Title: One

', $files['articles/one/index.html']); + $this->assertStringContainsString('

Article Title: Two

', $files['articles/two/index.html']); + $this->assertStringContainsString('

Article Title: Three

', $files['articles/three/index.html']); + $this->assertStringContainsString('

Article Title: Four

', $files['articles/four/index.html']); + $this->assertStringContainsString('

Article Title: Five

', $files['articles/five/index.html']); + $this->assertStringContainsString('

Article Title: Six

', $files['articles/six/index.html']); + $this->assertStringContainsString('

Article Title: Seven

', $files['articles/seven/index.html']); + $this->assertStringContainsString('

Article Title: Eight

', $files['articles/eight/index.html']); + } + + /** @test */ + public function it_generates_pages_to_custom_destination() + { + Config::set('statamic.ssg.destination', $this->destination = base_path('custom_export')); + + $this->generate(); + + $this->assertFalse($this->files->exists(storage_path('app/static'))); + $this->assertCount(13, $this->files->allFiles(base_path('custom_export'))); + + $this->cleanUpDestination(); + } + + /** @test */ + public function it_generates_paginated_pages() + { + $this->files->put(resource_path('views/articles/index.antlers.html'), <<<'EOT' +{{ collection:articles sort="date:asc" paginate="3" as="articles" }} + {{ articles }} + {{ title }} + {{ /articles }} + + {{ paginate }} + Current Page: {{ current_page }} + Total Pages: {{ total_pages }} + Prev Link: {{ prev_page }} + Next Link: {{ next_page }} + {{ /paginate }} +{{ /collection:articles }} +EOT + ); + + $this->generate(); + + $files = $this->getGeneratedFilesAtPath($this->destinationPath('articles')); + + $expectedArticlesFiles = [ + 'articles/index.html', + 'articles/page/1/index.html', + 'articles/page/2/index.html', + 'articles/page/3/index.html', + 'articles/one/index.html', + 'articles/two/index.html', + 'articles/three/index.html', + 'articles/four/index.html', + 'articles/five/index.html', + 'articles/six/index.html', + 'articles/seven/index.html', + 'articles/eight/index.html', + ]; + + $this->assertEqualsCanonicalizing($expectedArticlesFiles, array_keys($files)); + + // Index assertions on implicit page 1 + $index = $files['articles/index.html']; + $this->assertStringContainsStrings(['One', 'Two', 'Three'], $index); + $this->assertStringNotContainsStrings(['Four', 'Five', 'Six'], $index); + $this->assertStringNotContainsStrings(['Seven', 'Eight'], $index); + $this->assertStringContainsString('Current Page: 1', $index); + $this->assertStringContainsString('Total Pages: 3', $index); + $this->assertStringContainsString('Next Link: /articles/page/2', $index); + + // Index assertions on explicit page 1 + $index = $files['articles/page/1/index.html']; + $this->assertStringContainsStrings(['One', 'Two', 'Three'], $index); + $this->assertStringNotContainsStrings(['Four', 'Five', 'Six'], $index); + $this->assertStringNotContainsStrings(['Seven', 'Eight'], $index); + $this->assertStringContainsString('Current Page: 1', $index); + $this->assertStringContainsString('Total Pages: 3', $index); + $this->assertStringContainsString('Next Link: /articles/page/2', $index); + + // Index assertions on page 2 + $index = $files['articles/page/2/index.html']; + $this->assertStringNotContainsStrings(['One', 'Two', 'Three'], $index); + $this->assertStringContainsStrings(['Four', 'Five', 'Six'], $index); + $this->assertStringNotContainsStrings(['Seven', 'Eight'], $index); + $this->assertStringContainsString('Current Page: 2', $index); + $this->assertStringContainsString('Total Pages: 3', $index); + $this->assertStringContainsString('Prev Link: /articles/page/1', $index); + $this->assertStringContainsString('Next Link: /articles/page/3', $index); + + // Index assertions on page 3 + $index = $files['articles/page/3/index.html']; + $this->assertStringNotContainsStrings(['One', 'Two', 'Three'], $index); + $this->assertStringNotContainsStrings(['Four', 'Five', 'Six'], $index); + $this->assertStringContainsStrings(['Seven', 'Eight'], $index); + $this->assertStringContainsString('Current Page: 3', $index); + $this->assertStringContainsString('Total Pages: 3', $index); + $this->assertStringContainsString('Prev Link: /articles/page/2', $index); + } + + /** @test */ + public function it_generates_pagination_with_custom_page_name_and_route() + { + // Here we'll override the `pagination_route`. + Config::set('statamic.ssg.pagination_route', '{url}/{page_name}-{page_number}'); + + // And we'll also use a custom `page_name` param. + // This could even be passed in as a translatable string if the user wants `page` in different languages, etc. + $this->files->put(resource_path('views/articles/index.antlers.html'), <<<'EOT' +{{ collection:articles sort="date:asc" paginate="3" page_name="p" as="articles" }} + {{ articles }} + {{ title }} + {{ /articles }} + + {{ paginate }} + Current Page: {{ current_page }} + Total Pages: {{ total_pages }} + Prev Link: {{ prev_page }} + Next Link: {{ next_page }} + {{ /paginate }} +{{ /collection:articles }} +EOT + ); + + $this->generate(); + + $files = $this->getGeneratedFilesAtPath($this->destinationPath('articles')); + + $expectedArticlesFiles = [ + 'articles/index.html', + 'articles/p-1/index.html', + 'articles/p-2/index.html', + 'articles/p-3/index.html', + 'articles/one/index.html', + 'articles/two/index.html', + 'articles/three/index.html', + 'articles/four/index.html', + 'articles/five/index.html', + 'articles/six/index.html', + 'articles/seven/index.html', + 'articles/eight/index.html', + ]; + + $this->assertEqualsCanonicalizing($expectedArticlesFiles, array_keys($files)); + + // Index assertions on implicit page 1 + $index = $files['articles/index.html']; + $this->assertStringContainsStrings(['One', 'Two', 'Three'], $index); + $this->assertStringNotContainsStrings(['Four', 'Five', 'Six'], $index); + $this->assertStringNotContainsStrings(['Seven', 'Eight'], $index); + $this->assertStringContainsString('Current Page: 1', $index); + $this->assertStringContainsString('Total Pages: 3', $index); + $this->assertStringContainsString('Next Link: /articles/p-2', $index); + + // Index assertions on explicit page 1 + $index = $files['articles/p-1/index.html']; + $this->assertStringContainsStrings(['One', 'Two', 'Three'], $index); + $this->assertStringNotContainsStrings(['Four', 'Five', 'Six'], $index); + $this->assertStringNotContainsStrings(['Seven', 'Eight'], $index); + $this->assertStringContainsString('Current Page: 1', $index); + $this->assertStringContainsString('Total Pages: 3', $index); + $this->assertStringContainsString('Next Link: /articles/p-2', $index); + + // Index assertions on page 2 + $index = $files['articles/p-2/index.html']; + $this->assertStringNotContainsStrings(['One', 'Two', 'Three'], $index); + $this->assertStringContainsStrings(['Four', 'Five', 'Six'], $index); + $this->assertStringNotContainsStrings(['Seven', 'Eight'], $index); + $this->assertStringContainsString('Current Page: 2', $index); + $this->assertStringContainsString('Total Pages: 3', $index); + $this->assertStringContainsString('Prev Link: /articles/p-1', $index); + $this->assertStringContainsString('Next Link: /articles/p-3', $index); + + // Index assertions on page 3 + $index = $files['articles/p-3/index.html']; + $this->assertStringNotContainsStrings(['One', 'Two', 'Three'], $index); + $this->assertStringNotContainsStrings(['Four', 'Five', 'Six'], $index); + $this->assertStringContainsStrings(['Seven', 'Eight'], $index); + $this->assertStringContainsString('Current Page: 3', $index); + $this->assertStringContainsString('Total Pages: 3', $index); + $this->assertStringContainsString('Prev Link: /articles/p-2', $index); + } +} diff --git a/tests/Localized/GenerateTest.php b/tests/Localized/GenerateTest.php new file mode 100644 index 0000000..b689542 --- /dev/null +++ b/tests/Localized/GenerateTest.php @@ -0,0 +1,241 @@ +set('statamic.editions.pro', true); + + $app['config']->set('statamic.sites.sites', [ + 'default' => [ + 'name' => 'English', + 'locale' => 'en_US', + 'url' => '/', + ], + 'french' => [ + 'name' => 'French', + 'locale' => 'fr_FR', + 'url' => '/fr/', + ], + 'italian' => [ + 'name' => 'Italian', + 'locale' => 'it_IT', + 'url' => '/it/', + ], + ]); + } + + /** @test */ + public function it_generates_pages_for_localized_site_fixture() + { + $files = $this->generate(); + + $expectedFiles = [ + '404.html', + 'index.html', + 'about/index.html', + 'topics/index.html', + 'articles/index.html', + 'articles/one/index.html', + 'articles/two/index.html', + 'articles/three/index.html', + 'articles/four/index.html', + 'articles/five/index.html', + 'articles/six/index.html', + 'articles/seven/index.html', + 'articles/eight/index.html', + 'fr/index.html', + 'fr/le-about/index.html', + 'fr/le-topics/index.html', + 'fr/le-articles/index.html', + 'fr/le-articles/le-one/index.html', + 'fr/le-articles/le-two/index.html', + 'fr/le-articles/le-three/index.html', + 'fr/le-articles/le-four/index.html', + 'fr/le-articles/le-five/index.html', + ]; + + $this->assertEqualsCanonicalizing($expectedFiles, array_keys($files)); + + $this->assertStringContainsString('

404!

', $files['404.html']); + + $this->assertStringContainsString('

Page Title: Home

', $files['index.html']); + $this->assertStringContainsString('

Page Title: About

', $files['about/index.html']); + $this->assertStringContainsString('

Page Title: Topics

', $files['topics/index.html']); + + $this->assertStringContainsString('

Articles Index Page Title

', $index = $files['articles/index.html']); + $this->assertStringContainsString('One', $index); + $this->assertStringContainsString('Two', $index); + $this->assertStringContainsString('Three', $index); + $this->assertStringContainsString('Four', $index); + $this->assertStringContainsString('Five', $index); + $this->assertStringContainsString('Six', $index); + $this->assertStringContainsString('Seven', $index); + $this->assertStringContainsString('Eight', $index); + + $this->assertStringContainsString('

Article Title: One

', $files['articles/one/index.html']); + $this->assertStringContainsString('

Article Title: Two

', $files['articles/two/index.html']); + $this->assertStringContainsString('

Article Title: Three

', $files['articles/three/index.html']); + $this->assertStringContainsString('

Article Title: Four

', $files['articles/four/index.html']); + $this->assertStringContainsString('

Article Title: Five

', $files['articles/five/index.html']); + $this->assertStringContainsString('

Article Title: Six

', $files['articles/six/index.html']); + $this->assertStringContainsString('

Article Title: Seven

', $files['articles/seven/index.html']); + $this->assertStringContainsString('

Article Title: Eight

', $files['articles/eight/index.html']); + + $this->assertStringContainsString('

Page Title: Le Home

', $files['fr/index.html']); + $this->assertStringContainsString('

Page Title: Le About

', $files['fr/le-about/index.html']); + $this->assertStringContainsString('

Page Title: Le Topics

', $files['fr/le-topics/index.html']); + + $this->assertStringContainsString('

Articles Index Page Title

', $index = $files['fr/le-articles/index.html']); + $this->assertStringContainsString('Le One', $index); + $this->assertStringContainsString('Le Two', $index); + $this->assertStringContainsString('Le Three', $index); + $this->assertStringContainsString('Le Four', $index); + $this->assertStringContainsString('Le Five', $index); + + $this->assertStringContainsString('

Article Title: Le One

', $files['fr/le-articles/le-one/index.html']); + $this->assertStringContainsString('

Article Title: Le Two

', $files['fr/le-articles/le-two/index.html']); + $this->assertStringContainsString('

Article Title: Le Three

', $files['fr/le-articles/le-three/index.html']); + $this->assertStringContainsString('

Article Title: Le Four

', $files['fr/le-articles/le-four/index.html']); + $this->assertStringContainsString('

Article Title: Le Five

', $files['fr/le-articles/le-five/index.html']); + } + + /** @test */ + public function it_generates_localized_paginated_pages() + { + $this->files->put(resource_path('views/articles/index.antlers.html'), <<<'EOT' +{{ collection:articles sort="date:asc" paginate="3" as="articles" }} + {{ articles }} + {{ title }} + {{ /articles }} + + {{ paginate }} + Current Page: {{ current_page }} + Total Pages: {{ total_pages }} + Prev Link: {{ prev_page }} + Next Link: {{ next_page }} + {{ /paginate }} +{{ /collection:articles }} +EOT + ); + + $this->generate(); + + $files = $this->getGeneratedFilesAtPath($this->destinationPath('fr/le-articles')); + + $expectedArticlesFiles = [ + 'fr/le-articles/index.html', + 'fr/le-articles/page/1/index.html', + 'fr/le-articles/page/2/index.html', + 'fr/le-articles/le-one/index.html', + 'fr/le-articles/le-two/index.html', + 'fr/le-articles/le-three/index.html', + 'fr/le-articles/le-four/index.html', + 'fr/le-articles/le-five/index.html', + ]; + + $this->assertEqualsCanonicalizing($expectedArticlesFiles, array_keys($files)); + + // Index assertions on implicit page 1 + $index = $files['fr/le-articles/index.html']; + $this->assertStringContainsStrings(['Le One', 'Le Two', 'Le Three'], $index); + $this->assertStringNotContainsStrings(['Le Four', 'Le Five'], $index); + $this->assertStringContainsString('Current Page: 1', $index); + $this->assertStringContainsString('Total Pages: 2', $index); + $this->assertStringContainsString('Next Link: /fr/le-articles/page/2', $index); + + // Index assertions on explicit page 1 + $index = $files['fr/le-articles/page/1/index.html']; + $this->assertStringContainsStrings(['Le One', 'Le Two', 'Le Three'], $index); + $this->assertStringNotContainsStrings(['Le Four', 'Le Five'], $index); + $this->assertStringContainsString('Current Page: 1', $index); + $this->assertStringContainsString('Total Pages: 2', $index); + $this->assertStringContainsString('Next Link: /fr/le-articles/page/2', $index); + + // Index assertions on page 2 + $index = $files['fr/le-articles/page/2/index.html']; + $this->assertStringNotContainsStrings(['Le One', 'Le Two', 'Le Three'], $index); + $this->assertStringContainsStrings(['Le Four', 'Le Five'], $index); + $this->assertStringContainsString('Current Page: 2', $index); + $this->assertStringContainsString('Total Pages: 2', $index); + $this->assertStringContainsString('Prev Link: /fr/le-articles/page/1', $index); + } + + /** @test */ + public function it_generates_localized_pagination_with_custom_page_name_and_route() + { + // Here we'll override the `pagination_route`. + Config::set('statamic.ssg.pagination_route', '{url}/{page_name}-{page_number}'); + + // And we'll also use a custom `page_name` param. + // This could even be passed in as a translatable string if the user wants `page` in different languages, etc. + $this->files->put(resource_path('views/articles/index.antlers.html'), <<<'EOT' +{{ collection:articles sort="date:asc" paginate="3" page_name="p" as="articles" }} + {{ articles }} + {{ title }} + {{ /articles }} + + {{ paginate }} + Current Page: {{ current_page }} + Total Pages: {{ total_pages }} + Prev Link: {{ prev_page }} + Next Link: {{ next_page }} + {{ /paginate }} +{{ /collection:articles }} +EOT + ); + + $this->generate(); + + $files = $this->getGeneratedFilesAtPath($this->destinationPath('fr/le-articles')); + + $expectedArticlesFiles = [ + 'fr/le-articles/index.html', + 'fr/le-articles/p-1/index.html', + 'fr/le-articles/p-2/index.html', + 'fr/le-articles/le-one/index.html', + 'fr/le-articles/le-two/index.html', + 'fr/le-articles/le-three/index.html', + 'fr/le-articles/le-four/index.html', + 'fr/le-articles/le-five/index.html', + ]; + + $this->assertEqualsCanonicalizing($expectedArticlesFiles, array_keys($files)); + + // Index assertions on implicit page 1 + $index = $files['fr/le-articles/index.html']; + $this->assertStringContainsStrings(['Le One', 'Le Two', 'Le Three'], $index); + $this->assertStringNotContainsStrings(['Le Four', 'Le Five'], $index); + $this->assertStringContainsString('Current Page: 1', $index); + $this->assertStringContainsString('Total Pages: 2', $index); + $this->assertStringContainsString('Next Link: /fr/le-articles/p-2', $index); + + // Index assertions on explicit page 1 + $index = $files['fr/le-articles/p-1/index.html']; + $this->assertStringContainsStrings(['Le One', 'Le Two', 'Le Three'], $index); + $this->assertStringNotContainsStrings(['Le Four', 'Le Five'], $index); + $this->assertStringContainsString('Current Page: 1', $index); + $this->assertStringContainsString('Total Pages: 2', $index); + $this->assertStringContainsString('Next Link: /fr/le-articles/p-2', $index); + + // Index assertions on page 2 + $index = $files['fr/le-articles/p-2/index.html']; + $this->assertStringNotContainsStrings(['Le One', 'Le Two', 'Le Three'], $index); + $this->assertStringContainsStrings(['Le Four', 'Le Five'], $index); + $this->assertStringContainsString('Current Page: 2', $index); + $this->assertStringContainsString('Total Pages: 2', $index); + $this->assertStringContainsString('Prev Link: /fr/le-articles/p-1', $index); + } +} diff --git a/tests/RequestTest.php b/tests/RequestTest.php index 858eb98..7cd6a8d 100644 --- a/tests/RequestTest.php +++ b/tests/RequestTest.php @@ -54,4 +54,18 @@ public function gets_path() $this->assertEquals('foo', $request->path()); } + + /** @test */ + public function it_can_forget_query_param() + { + $request = new Request; + + $request->merge(['page' => 2]); + + $this->assertEquals(['page' => 2], $request->all()); + + $request->forget('page'); + + $this->assertEquals([], $request->all()); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 93552a4..ee9d431 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,16 +2,21 @@ namespace Tests; +use Illuminate\Filesystem\Filesystem; use Orchestra\Testbench\TestCase as OrchestraTestCase; -use Statamic\Providers\StatamicServiceProvider; use Statamic\Statamic; class TestCase extends OrchestraTestCase { + protected $fixturePath = __DIR__.'/Fixtures'; + protected $siteFixture = 'site'; + protected function getPackageProviders($app) { return [ - StatamicServiceProvider::class, + \Statamic\Providers\StatamicServiceProvider::class, + \Wilderborn\Partyline\ServiceProvider::class, + \Statamic\StaticSite\ServiceProvider::class, ]; } @@ -21,4 +26,56 @@ protected function getPackageAliases($app) 'Statamic' => Statamic::class, ]; } + + protected function setUp(): void + { + parent::setUp(); + + $this->files = app(Filesystem::class); + + $this->copyDirectoryFromFixture('resources'); + $this->copyDirectoryFromSiteFixture('content'); + + $this->app->instance('fork-installed', false); + } + + protected function copyDirectoryFromFixture($directory, $site = null) + { + if (base_path($directory)) { + $this->files->deleteDirectory(base_path($directory)); + } + + $origin = vsprintf('%s/%s%s', [ + $this->fixturePath, + $site ? "{$site}/" : '', + $directory, + ]); + + $this->files->copyDirectory($origin, base_path($directory)); + } + + protected function copyDirectoryFromSiteFixture($directory) + { + $this->copyDirectoryFromFixture($directory, $this->siteFixture); + } + + protected function resolveApplicationConfiguration($app) + { + parent::resolveApplicationConfiguration($app); + + $configs = [ + 'assets', 'cp', 'forms', 'routes', 'static_caching', + 'sites', 'stache', 'system', 'users', + ]; + + foreach ($configs as $config) { + $app['config']->set("statamic.$config", require(__DIR__."/../vendor/statamic/cms/config/{$config}.php")); + } + } + + protected function getEnvironmentSetUp($app) + { + $app['config']->set('auth.providers.users.driver', 'statamic'); + $app['config']->set('statamic.users.repository', 'file'); + } }