Passed
Push — master ( a80842...bbbee0 )
by Caen
03:37 queued 13s
created

MakePublicationTypeCommandTest   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 212
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 103
dl 0
loc 212
rs 10
c 3
b 0
f 0
wmc 8
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Publications\Testing\Feature;
6
7
use Hyde\Hyde;
8
use Hyde\Testing\TestCase;
9
use Hyde\Facades\Filesystem;
10
use Hyde\Publications\Concerns\PublicationFieldTypes;
11
12
/**
13
 * @covers \Hyde\Publications\Commands\MakePublicationTypeCommand
14
 * @covers \Hyde\Publications\Actions\CreatesNewPublicationType
15
 */
16
class MakePublicationTypeCommandTest extends TestCase
17
{
18
    protected const selectPageSizeQuestion = 'How many links should be shown on the listing page? <fg=gray>(any value above 0 will enable <href=https://docs.hydephp.com/search?query=pagination>pagination</>)</>';
19
    protected const selectCanonicalNameQuestion = 'Choose a canonical name field <fg=gray>(this will be used to generate filenames, so the values need to be unique)</>';
20
    protected const expectedEnumCases = ['String', 'Datetime', 'Boolean', 'Integer', 'Float', 'Array', 'Media', 'Text', 'Tag', 'Url'];
21
22
    protected function setUp(): void
23
    {
24
        parent::setUp();
25
26
        $this->throwOnConsoleException();
27
    }
28
29
    protected function tearDown(): void
30
    {
31
        Filesystem::deleteDirectory('test-publication');
32
33
        parent::tearDown();
34
    }
35
36
    public function test_command_creates_publication_type()
37
    {
38
        $this->artisan('make:publicationType')
39
            ->expectsQuestion('Publication type name', 'Test Publication')
40
            ->expectsQuestion('Enter name for field #1', 'Publication Title')
41
            ->expectsChoice('Enter type for field #1', 'String', [
42
                'String',
43
                'Datetime',
44
                'Boolean',
45
                'Integer',
46
                'Float',
47
                'Array',
48
                'Media',
49
                'Text',
50
                'Tag',
51
                'Url',
52
            ], true)
53
            ->expectsConfirmation('Field #1 added! Add another field?')
54
55
            ->expectsChoice(self::selectCanonicalNameQuestion, 'publication-title', [
56
                '__createdAt',
57
                'publication-title',
58
            ])
59
60
            ->expectsChoice('Choose the field you wish to sort by', '__createdAt', [
61
                '__createdAt',
62
                'publication-title',
63
            ])
64
            ->expectsChoice('Choose the sort direction', 'Ascending', [
65
                'Ascending',
66
                'Descending',
67
            ])
68
            ->expectsQuestion(self::selectPageSizeQuestion, 10)
69
70
            ->expectsOutputToContain('Creating a new Publication Type!')
71
            ->expectsOutput('Saving publication data to [test-publication/schema.json]')
72
            ->expectsOutput('Publication type created successfully!')
73
            ->assertExitCode(0);
74
75
        $this->assertFileExists(Hyde::path('test-publication/schema.json'));
76
        $this->assertEquals(
77
            <<<'JSON'
78
            {
79
                "name": "Test Publication",
80
                "canonicalField": "publication-title",
81
                "detailTemplate": "detail.blade.php",
82
                "listTemplate": "list.blade.php",
83
                "sortField": "__createdAt",
84
                "sortAscending": true,
85
                "pageSize": 10,
86
                "fields": [
87
                    {
88
                        "type": "string",
89
                        "name": "publication-title"
90
                    }
91
                ]
92
            }
93
            JSON,
94
            file_get_contents(Hyde::path('test-publication/schema.json'))
95
        );
96
97
        $this->assertFileExists(Hyde::path('test-publication/detail.blade.php'));
98
        $this->assertFileExists(Hyde::path('test-publication/list.blade.php'));
99
100
        $this->assertStringContainsString('paginator', file_get_contents(Hyde::path('test-publication/list.blade.php')));
101
    }
102
103
    public function test_with_default_values()
104
    {
105
        // When running this command with the no-interaction flag in an actual console, no questions are asked.
106
        // However, when running it in a test, the questions are still asked, presumably due to a vendor bug.
107
108
        $this->withoutMockingConsoleOutput();
109
110
        $this->assertSame(0, $this->artisan('make:publicationType "Test Publication" --no-interaction'));
111
112
        $this->assertFileExists(Hyde::path('test-publication/schema.json'));
113
        $this->assertEquals(
114
            <<<'JSON'
115
            {
116
                "name": "Test Publication",
117
                "canonicalField": "__createdAt",
118
                "detailTemplate": "detail.blade.php",
119
                "listTemplate": "list.blade.php",
120
                "sortField": "__createdAt",
121
                "sortAscending": true,
122
                "pageSize": 0,
123
                "fields": [
124
                    {
125
                        "type": "string",
126
                        "name": "example-field"
127
                    }
128
                ]
129
            }
130
            JSON,
131
            file_get_contents(Hyde::path('test-publication/schema.json'))
132
        );
133
134
        $this->assertFileExists(Hyde::path('test-publication/detail.blade.php'));
135
        $this->assertFileExists(Hyde::path('test-publication/list.blade.php'));
136
137
        $this->assertStringNotContainsString('paginator', file_get_contents(Hyde::path('test-publication/list.blade.php')));
138
    }
139
140
    public function test_with_multiple_fields_of_the_same_name()
141
    {
142
        $this->artisan('make:publicationType "Test Publication"')
143
144
            ->expectsQuestion('Enter name for field #1', 'foo')
145
            ->expectsChoice('Enter type for field #1', 'String', PublicationFieldTypes::names())
146
147
            ->expectsConfirmation('Field #1 added! Add another field?', 'yes')
148
149
            ->expectsQuestion('Enter name for field #2', 'foo')
150
            ->expectsOutput('Field name [foo] already exists!')
151
            ->expectsQuestion('Try again: Enter name for field #2', 'bar')
152
            ->expectsChoice('Enter type for field #2', 'String', PublicationFieldTypes::names())
153
154
            ->expectsConfirmation('Field #2 added! Add another field?')
155
156
            ->expectsChoice(self::selectCanonicalNameQuestion, 'foo', [
157
                '__createdAt',
158
                'bar',
159
                'foo',
160
            ])
161
162
            ->expectsChoice('Choose the field you wish to sort by', '__createdAt', ['__createdAt', 'foo', 'bar'])
163
            ->expectsChoice('Choose the sort direction', 'Ascending', ['Ascending', 'Descending'])
164
            ->expectsQuestion(self::selectPageSizeQuestion, 0)
165
166
            ->assertExitCode(0);
167
    }
168
169
    public function test_with_existing_file_of_the_same_name()
170
    {
171
        $this->throwOnConsoleException(false);
172
173
        $this->file('test-publication');
174
175
        $this->artisan('make:publicationType "Test Publication"')
176
            ->expectsOutput('Error: Storage path [test-publication] already exists')
177
            ->assertExitCode(1);
178
    }
179
180
    public function test_with_existing_publication_of_the_same_name()
181
    {
182
        $this->throwOnConsoleException(false);
183
184
        $this->directory('test-publication');
185
        $this->file('test-publication/foo');
186
187
        $this->artisan('make:publicationType "Test Publication"')
188
             ->expectsOutput('Error: Storage path [test-publication] already exists')
189
             ->assertExitCode(1);
190
    }
191
192
    public function testWithTagFieldInput()
193
    {
194
        $this->directory('test-publication');
195
196
        $this->artisan('make:publicationType "Test Publication"')
197
            ->expectsQuestion('Enter name for field #1', 'MyTag')
198
            ->expectsChoice('Enter type for field #1', 'Tag',
199
                self::expectedEnumCases)
200
            ->expectsConfirmation('Field #1 added! Add another field?')
201
            ->expectsChoice(self::selectCanonicalNameQuestion, '__createdAt', ['__createdAt'])
202
            ->expectsChoice('Choose the field you wish to sort by', '__createdAt', ['__createdAt'])
203
            ->expectsChoice('Choose the sort direction', 'Ascending', ['Ascending', 'Descending'])
204
            ->expectsQuestion(self::selectPageSizeQuestion, 0)
205
206
            ->assertSuccessful();
207
208
        $this->assertFileExists(Hyde::path('test-publication/schema.json'));
209
        $this->assertFileEqualsString(
210
            <<<'JSON'
211
            {
212
                "name": "Test Publication",
213
                "canonicalField": "__createdAt",
214
                "detailTemplate": "detail.blade.php",
215
                "listTemplate": "list.blade.php",
216
                "sortField": "__createdAt",
217
                "sortAscending": true,
218
                "pageSize": 0,
219
                "fields": [
220
                    {
221
                        "type": "tag",
222
                        "name": "my-tag"
223
                    }
224
                ]
225
            }
226
            JSON,
227
            'test-publication/schema.json');
228
    }
229
}
230