1+ <?php
2+
3+ namespace Tests \Feature \Settings ;
4+
5+ use App \Models \Labels \CustomUserLabel ;
6+ use App \Models \User ;
7+ use Tests \TestCase ;
8+
9+ class CustomLabelCrudTest extends TestCase
10+ {
11+ private function sheetPayload (array $ overrides = []): array
12+ {
13+ return array_replace_recursive ([
14+ 'name ' => 'My Sheet Label ' ,
15+ 'template ' => 'DefaultLabel ' ,
16+ 'type ' => 'sheet ' ,
17+ 'content ' => [
18+ 'tag_font ' => 'freemono ' ,
19+ 'title_font ' => 'freesans ' ,
20+ 'field_label_font ' => 'freesans ' ,
21+ 'field_value_font ' => 'freemono ' ,
22+ 'barcode_size ' => 3.81 ,
23+ 'barcode_margin ' => 0.3 ,
24+ ],
25+ 'supports ' => [
26+ 'asset_tag ' => false ,
27+ 'barcode_1d ' => true ,
28+ 'barcode_2d ' => true ,
29+ 'fields ' => 4 ,
30+ 'logo ' => true ,
31+ 'title ' => true ,
32+ ],
33+ 'page ' => [
34+ 'width ' => 215.9 ,
35+ 'height ' => 279.4 ,
36+ 'margin_top ' => 12.7 ,
37+ 'margin_right ' => 5.58 ,
38+ 'margin_bottom ' => 12.7 ,
39+ 'margin_left ' => 5.58 ,
40+ ],
41+ 'grid ' => [
42+ 'columns ' => 3 ,
43+ 'rows ' => 9 ,
44+ 'column_spacing ' => 1.27 ,
45+ 'row_spacing ' => 1.778 ,
46+ ],
47+ 'label ' => [
48+ 'width ' => 66.675 ,
49+ 'height ' => 25.4 ,
50+ 'border ' => 0 ,
51+ 'padding_top ' => 0 ,
52+ 'padding_right ' => 0 ,
53+ 'padding_bottom ' => 0 ,
54+ 'padding_left ' => 0 ,
55+ ],
56+ ], $ overrides );
57+ }
58+
59+ private function tapePayload (array $ overrides = []): array
60+ {
61+ return array_replace_recursive ([
62+ 'name ' => 'My Tape Label ' ,
63+ 'template ' => 'StandardTape ' ,
64+ 'type ' => 'tape ' ,
65+ 'content ' => [
66+ 'tag_font ' => 'freemono ' ,
67+ 'title_font ' => 'freesans ' ,
68+ 'field_label_font ' => 'freesans ' ,
69+ 'field_value_font ' => 'freemono ' ,
70+ 'barcode_size ' => 6 ,
71+ 'barcode_margin ' => 1 ,
72+ ],
73+ 'supports ' => [
74+ 'asset_tag ' => true ,
75+ 'barcode_1d ' => true ,
76+ 'barcode_2d ' => true ,
77+ 'fields ' => 5 ,
78+ 'logo ' => true ,
79+ 'title ' => true ,
80+ ],
81+ 'dimensions ' => [
82+ 'width ' => 50 ,
83+ 'height ' => 24 ,
84+ 'label_gap ' => 3 ,
85+ ],
86+ ], $ overrides );
87+ }
88+
89+ private function makeCustomTapeLabel (array $ attributes = []): CustomUserLabel
90+ {
91+ return CustomUserLabel::create (array_replace ([
92+ 'name ' => 'Existing Tape Label ' ,
93+ 'base_label ' => 'StandardTape ' ,
94+ 'type ' => 'tape ' ,
95+ 'overrides ' => [],
96+ 'config_snapshot ' => [
97+ 'unit ' => 'mm ' ,
98+ 'template ' => 'StandardTape ' ,
99+ 'type ' => 'tape ' ,
100+ 'name ' => 'Existing Tape Label ' ,
101+ 'dimensions ' => ['width ' => 50.0 , 'height ' => 24.0 , 'label_gap ' => 3.0 ],
102+ 'content ' => $ this ->tapePayload ()['content ' ],
103+ 'supports ' => $ this ->tapePayload ()['supports ' ],
104+ ],
105+ 'is_default ' => false ,
106+ ], $ attributes ));
107+ }
108+
109+ public function test_store_creates_sheet_label_with_submitted_grid (): void
110+ {
111+ $ this ->actingAs (User::factory ()->superuser ()->create ())
112+ ->post (route ('settings.labels.store ' ), $ this ->sheetPayload ([
113+ 'grid ' => ['rows ' => 7 , 'columns ' => 2 ],
114+ ]))
115+ ->assertRedirect (route ('settings.labels.index ' ))
116+ ->assertSessionHas ('success ' );
117+
118+ $ label = CustomUserLabel::where ('name ' , 'My Sheet Label ' )->firstOrFail ();
119+
120+ $ this ->assertSame ('sheet ' , $ label ->type );
121+ $ this ->assertSame ('DefaultLabel ' , $ label ->base_label );
122+ $ this ->assertEquals (7 , $ label ->config_snapshot ['grid ' ]['rows ' ]);
123+ $ this ->assertEquals (2 , $ label ->config_snapshot ['grid ' ]['columns ' ]);
124+ }
125+
126+ public function test_store_creates_tape_label_with_submitted_dimensions (): void
127+ {
128+ $ this ->actingAs (User::factory ()->superuser ()->create ())
129+ ->post (route ('settings.labels.store ' ), $ this ->tapePayload ([
130+ 'dimensions ' => ['width ' => 62 , 'height ' => 29 , 'label_gap ' => 2 ],
131+ ]))
132+ ->assertRedirect (route ('settings.labels.index ' ))
133+ ->assertSessionHas ('success ' );
134+
135+ $ label = CustomUserLabel::where ('name ' , 'My Tape Label ' )->firstOrFail ();
136+
137+ $ this ->assertSame ('tape ' , $ label ->type );
138+ $ this ->assertArrayHasKey ('dimensions ' , $ label ->config_snapshot );
139+ $ this ->assertEquals (62 , $ label ->config_snapshot ['dimensions ' ]['width ' ]);
140+ $ this ->assertEquals (29 , $ label ->config_snapshot ['dimensions ' ]['height ' ]);
141+ $ this ->assertEquals (2 , $ label ->config_snapshot ['dimensions ' ]['label_gap ' ]);
142+ }
143+
144+ public function test_store_rejects_zero_rows_and_columns_for_sheet (): void
145+ {
146+ $ this ->actingAs (User::factory ()->superuser ()->create ())
147+ ->post (route ('settings.labels.store ' ), $ this ->sheetPayload ([
148+ 'grid ' => ['rows ' => 0 , 'columns ' => 0 ],
149+ ]))
150+ ->assertSessionHasErrors (['grid.rows ' , 'grid.columns ' ]);
151+
152+ $ this ->assertDatabaseCount ('custom_user_labels ' , 0 );
153+ }
154+
155+ public function test_store_rejects_non_positive_tape_dimensions (): void
156+ {
157+ $ this ->actingAs (User::factory ()->superuser ()->create ())
158+ ->post (route ('settings.labels.store ' ), $ this ->tapePayload ([
159+ 'dimensions ' => ['width ' => 0 , 'height ' => -5 ],
160+ ]))
161+ ->assertSessionHasErrors (['dimensions.width ' , 'dimensions.height ' ]);
162+
163+ $ this ->assertDatabaseCount ('custom_user_labels ' , 0 );
164+ }
165+
166+ public function test_update_persists_new_sheet_grid (): void
167+ {
168+ $ label = CustomUserLabel::create ([
169+ 'name ' => 'Existing Sheet Label ' ,
170+ 'base_label ' => 'DefaultLabel ' ,
171+ 'type ' => 'sheet ' ,
172+ 'overrides ' => [],
173+ 'config_snapshot ' => $ this ->sheetPayload (),
174+ 'is_default ' => false ,
175+ ]);
176+
177+ $ this ->actingAs (User::factory ()->superuser ()->create ())
178+ ->put (route ('settings.labels.update ' , $ label ), $ this ->sheetPayload ([
179+ 'name ' => 'Existing Sheet Label ' ,
180+ 'grid ' => ['rows ' => 5 , 'columns ' => 4 ],
181+ ]))
182+ ->assertRedirect (route ('settings.labels.index ' ))
183+ ->assertSessionHas ('success ' );
184+
185+ $ label ->refresh ();
186+
187+ $ this ->assertEquals (5 , $ label ->config_snapshot ['grid ' ]['rows ' ]);
188+ $ this ->assertEquals (4 , $ label ->config_snapshot ['grid ' ]['columns ' ]);
189+ }
190+
191+ public function test_update_persists_new_tape_dimensions (): void
192+ {
193+ $ label = $ this ->makeCustomTapeLabel ();
194+
195+ $ this ->actingAs (User::factory ()->superuser ()->create ())
196+ ->put (route ('settings.labels.update ' , $ label ), $ this ->tapePayload ([
197+ 'name ' => 'Existing Tape Label ' ,
198+ 'dimensions ' => ['width ' => 80 , 'height ' => 30 , 'label_gap ' => 5 ],
199+ ]))
200+ ->assertRedirect (route ('settings.labels.index ' ))
201+ ->assertSessionHas ('success ' );
202+
203+ $ label ->refresh ();
204+
205+ $ this ->assertArrayHasKey ('dimensions ' , $ label ->config_snapshot );
206+ $ this ->assertEquals (80 , $ label ->config_snapshot ['dimensions ' ]['width ' ]);
207+ $ this ->assertEquals (30 , $ label ->config_snapshot ['dimensions ' ]['height ' ]);
208+ $ this ->assertEquals (5 , $ label ->config_snapshot ['dimensions ' ]['label_gap ' ]);
209+ }
210+
211+ public function test_update_rejects_non_positive_tape_dimensions (): void
212+ {
213+ $ label = $ this ->makeCustomTapeLabel ();
214+
215+ $ this ->actingAs (User::factory ()->superuser ()->create ())
216+ ->put (route ('settings.labels.update ' , $ label ), $ this ->tapePayload ([
217+ 'dimensions ' => ['width ' => 0 , 'height ' => 0 ],
218+ ]))
219+ ->assertSessionHasErrors (['dimensions.width ' , 'dimensions.height ' ]);
220+ }
221+
222+ // ---------------------------------------------------------------
223+ // destroy() guard
224+ // ---------------------------------------------------------------
225+
226+ public function test_destroy_deletes_non_default_label (): void
227+ {
228+ $ label = $ this ->makeCustomTapeLabel (['is_default ' => false ]);
229+
230+ $ this ->actingAs (User::factory ()->superuser ()->create ())
231+ ->delete (route ('settings.labels.destroy ' , $ label ))
232+ ->assertRedirect (route ('settings.labels.index ' ))
233+ ->assertSessionHas ('success ' );
234+
235+ $ this ->assertSoftDeleted ($ label );
236+ }
237+
238+ public function test_destroy_blocks_deleting_the_default_label (): void
239+ {
240+ $ label = $ this ->makeCustomTapeLabel (['is_default ' => true ]);
241+
242+ $ this ->actingAs (User::factory ()->superuser ()->create ())
243+ ->delete (route ('settings.labels.destroy ' , $ label ))
244+ ->assertRedirect (route ('settings.labels.index ' ))
245+ ->assertSessionHas ('warning ' );
246+
247+ $ this ->assertNotSoftDeleted ($ label );
248+ }
249+ }
0 commit comments