Revert castaway's test - mildly bogus
[dbsrgits/DBIx-Class.git] / t / 96multi_create.t
CommitLineData
33dd4e80 1use strict;
af2d42c0 2use warnings;
33dd4e80 3
04ec3909 4use Test::More;
33dd4e80 5use lib qw(t/lib);
6use DBICTest;
7
72dacbc5 8plan tests => 58;
04ec3909 9
33dd4e80 10my $schema = DBICTest->init_schema();
11
c45f4e10 12# simple create + parent (the stuff $rs belongs_to)
04ec3909 13eval {
c45f4e10 14 my $cd = $schema->resultset('CD')->create({
04ec3909 15 artist => {
16 name => 'Fred Bloggs'
17 },
18 title => 'Some CD',
19 year => 1996
20 });
21
c45f4e10 22 isa_ok($cd, 'DBICTest::CD', 'Created CD object');
23 isa_ok($cd->artist, 'DBICTest::Artist', 'Created related Artist');
24 is($cd->artist->name, 'Fred Bloggs', 'Artist created correctly');
25};
26diag $@ if $@;
27
28# same as above but the child and parent have no values,
29# except for an explicit parent pk
30eval {
31 my $bm_rs = $schema->resultset('Bookmark');
32 my $bookmark = $bm_rs->create({
33 link => {
34 id => 66,
35 },
36 });
37
38 isa_ok($bookmark, 'DBICTest::Bookmark', 'Created Bookrmark object');
39 isa_ok($bookmark->link, 'DBICTest::Link', 'Created related Link');
40 is (
41 $bm_rs->search (
42 { 'link.title' => $bookmark->link->title },
43 { join => 'link' },
44 )->count,
45 1,
46 'Bookmark and link made it to the DB',
47 );
04ec3909 48};
49diag $@ if $@;
50
51# create over > 1 levels of has_many create (A => { has_many => { B => has_many => C } } )
52eval {
53 my $artist = $schema->resultset('Artist')->create(
54 { name => 'Fred 2',
55 cds => [
56 { title => 'Music to code by',
57 year => 2007,
58 tags => [
59 { 'tag' => 'rock' },
60 ],
61 },
62 ],
63 });
64
65 isa_ok($artist, 'DBICTest::Artist', 'Created Artist');
66 is($artist->name, 'Fred 2', 'Artist created correctly');
67 is($artist->cds->count, 1, 'One CD created for artist');
68 is($artist->cds->first->title, 'Music to code by', 'CD created correctly');
69 is($artist->cds->first->tags->count, 1, 'One tag created for CD');
70 is($artist->cds->first->tags->first->tag, 'rock', 'Tag created correctly');
71
72 # Create via update - add a new CD
73 $artist->update({
74 cds => [ $artist->cds,
75 { title => 'Yet another CD',
76 year => 2006,
77 },
78 ],
79 });
80 is(($artist->cds->search({}, { order_by => 'year' }))[0]->title, 'Yet another CD', 'Updated and added another CD');
81
82 my $newartist = $schema->resultset('Artist')->find_or_create({ name => 'Fred 2'});
83
84 is($newartist->name, 'Fred 2', 'Retrieved the artist');
85};
86diag $@ if $@;
87
88# nested find_or_create
89eval {
90 my $newartist2 = $schema->resultset('Artist')->find_or_create({
91 name => 'Fred 3',
92 cds => [
93 {
94 title => 'Noah Act',
95 year => 2007,
96 },
97 ],
98 });
99 is($newartist2->name, 'Fred 3', 'Created new artist with cds via find_or_create');
100};
101diag $@ if $@;
102
103# multiple same level has_many create
104eval {
105 my $artist2 = $schema->resultset('Artist')->create({
106 name => 'Fred 3',
107 cds => [
108 {
109 title => 'Music to code by',
110 year => 2007,
111 },
112 ],
113 cds_unordered => [
114 {
115 title => 'Music to code by',
116 year => 2007,
117 },
118 ]
119 });
120
121 is($artist2->in_storage, 1, 'artist with duplicate rels inserted okay');
122};
123diag $@ if $@;
3d8ee6ab 124
04ec3909 125# first create_related pass
126eval {
3d8ee6ab 127 my $artist = $schema->resultset('Artist')->first;
128
129 my $cd_result = $artist->create_related('cds', {
130
131 title => 'TestOneCD1',
132 year => 2007,
133 tracks => [
134
135 { position=>111,
136 title => 'TrackOne',
137 },
138 { position=>112,
139 title => 'TrackTwo',
140 }
141 ],
142
143 });
144
145 ok( $cd_result && ref $cd_result eq 'DBICTest::CD', "Got Good CD Class");
146 ok( $cd_result->title eq "TestOneCD1", "Got Expected Title");
147
148 my $tracks = $cd_result->tracks;
149
150 ok( ref $tracks eq "DBIx::Class::ResultSet", "Got Expected Tracks ResultSet");
151
152 foreach my $track ($tracks->all)
153 {
154 ok( $track && ref $track eq 'DBICTest::Track', 'Got Expected Track Class');
155 }
04ec3909 156};
157diag $@ if $@;
3d8ee6ab 158
04ec3909 159# second create_related with same arguments
160eval {
2ec8e594 161 my $artist = $schema->resultset('Artist')->first;
3d8ee6ab 162
2ec8e594 163 my $cd_result = $artist->create_related('cds', {
3d8ee6ab 164
2ec8e594 165 title => 'TestOneCD2',
3d8ee6ab 166 year => 2007,
167 tracks => [
168
169 { position=>111,
170 title => 'TrackOne',
171 },
172 { position=>112,
173 title => 'TrackTwo',
174 }
175 ],
176
9c6d6d93 177 liner_notes => { notes => 'I can haz liner notes?' },
178
3d8ee6ab 179 });
180
181 ok( $cd_result && ref $cd_result eq 'DBICTest::CD', "Got Good CD Class");
2ec8e594 182 ok( $cd_result->title eq "TestOneCD2", "Got Expected Title");
9c6d6d93 183 ok( $cd_result->notes eq 'I can haz liner notes?', 'Liner notes');
3d8ee6ab 184
185 my $tracks = $cd_result->tracks;
186
187 ok( ref $tracks eq "DBIx::Class::ResultSet", "Got Expected Tracks ResultSet");
188
189 foreach my $track ($tracks->all)
190 {
191 ok( $track && ref $track eq 'DBICTest::Track', 'Got Expected Track Class');
192 }
04ec3909 193};
194diag $@ if $@;
e5dddc05 195
04ec3909 196# create of parents of a record linker table
197eval {
198 my $cdp = $schema->resultset('CD_to_Producer')->create({
199 cd => { artist => 1, title => 'foo', year => 2000 },
200 producer => { name => 'jorge' }
201 });
202 ok($cdp, 'join table record created ok');
203};
204diag $@ if $@;
2bc3c81e 205
04ec3909 206#SPECIAL_CASE
207eval {
2bc3c81e 208 my $kurt_cobain = { name => 'Kurt Cobain' };
209
210 my $in_utero = $schema->resultset('CD')->new({
211 title => 'In Utero',
212 year => 1993
213 });
214
215 $kurt_cobain->{cds} = [ $in_utero ];
216
217
218 $schema->resultset('Artist')->populate([ $kurt_cobain ]); # %)
219 $a = $schema->resultset('Artist')->find({name => 'Kurt Cobain'});
220
221 is($a->name, 'Kurt Cobain', 'Artist insertion ok');
222 is($a->cds && $a->cds->first && $a->cds->first->title,
223 'In Utero', 'CD insertion ok');
04ec3909 224};
225diag $@ if $@;
2bc3c81e 226
04ec3909 227#SPECIAL_CASE2
228eval {
2bc3c81e 229 my $pink_floyd = { name => 'Pink Floyd' };
230
231 my $the_wall = { title => 'The Wall', year => 1979 };
232
233 $pink_floyd->{cds} = [ $the_wall ];
234
235
236 $schema->resultset('Artist')->populate([ $pink_floyd ]); # %)
237 $a = $schema->resultset('Artist')->find({name => 'Pink Floyd'});
238
239 is($a->name, 'Pink Floyd', 'Artist insertion ok');
240 is($a->cds && $a->cds->first->title, 'The Wall', 'CD insertion ok');
04ec3909 241};
242diag $@ if $@;
e02b9964 243
244## Create foreign key col obj including PK
245## See test 20 in 66relationships.t
04ec3909 246eval {
247 my $new_cd_hashref = {
248 cdid => 27,
249 title => 'Boogie Woogie',
250 year => '2007',
251 artist => { artistid => 17, name => 'king luke' }
252 };
e02b9964 253
04ec3909 254 my $cd = $schema->resultset("CD")->find(1);
f10ac17d 255
04ec3909 256 is($cd->artist->id, 1, 'rel okay');
f10ac17d 257
04ec3909 258 my $new_cd = $schema->resultset("CD")->create($new_cd_hashref);
259 is($new_cd->artist->id, 17, 'new id retained okay');
260};
261diag $@ if $@;
6ede9177 262
263eval {
264 $schema->resultset("CD")->create({
38c03c20 265 cdid => 28,
370f2ba2 266 title => 'Boogie Wiggle',
38c03c20 267 year => '2007',
268 artist => { artistid => 18, name => 'larry' }
6ede9177 269 });
38c03c20 270};
6ede9177 271is($@, '', 'new cd created without clash on related artist');
38c03c20 272
f10ac17d 273# Make sure exceptions from errors in created rels propogate
274eval {
370f2ba2 275 my $t = $schema->resultset("Track")->new({ cd => { artist => undef } });
276 #$t->cd($t->new_related('cd', { artist => undef } ) );
277 #$t->{_rel_in_storage} = 0;
f10ac17d 278 $t->insert;
279};
280like($@, qr/cd.artist may not be NULL/, "Exception propogated properly");
bbbf67eb 281
282# Test multi create over many_to_many
04ec3909 283eval {
284 $schema->resultset('CD')->create ({
285 artist => {
286 name => 'larry', # should already exist
287 },
76b8cf98 288 title => 'Warble Marble',
289 year => '2009',
290 cd_to_producer => [
04ec3909 291 { producer => { name => 'Cowboy Neal' } },
76b8cf98 292 ],
04ec3909 293 });
76b8cf98 294
04ec3909 295 my $m2m_cd = $schema->resultset('CD')->search ({ title => 'Warble Marble'});
296 is ($m2m_cd->count, 1, 'One CD row created via M2M create');
297 is ($m2m_cd->first->producers->count, 1, 'CD row created with one producer');
298 is ($m2m_cd->first->producers->first->name, 'Cowboy Neal', 'Correct producer row created');
299};
76b8cf98 300
301# and some insane multicreate
302# (should work, despite the fact that no one will probably use it this way)
303
04ec3909 304# first count how many rows do we initially have
76b8cf98 305my $counts;
04ec3909 306$counts->{$_} = $schema->resultset($_)->count for qw/Artist CD Genre Producer Tag/;
76b8cf98 307
308# do the crazy create
04ec3909 309eval {
310 $schema->resultset('CD')->create ({
311 artist => {
533292a0 312 name => 'james',
04ec3909 313 },
76b8cf98 314 title => 'Greatest hits 1',
315 year => '2012',
316 genre => {
317 name => '"Greatest" collections',
318 },
04ec3909 319 tags => [
320 { tag => 'A' },
321 { tag => 'B' },
322 ],
76b8cf98 323 cd_to_producer => [
324 {
325 producer => {
533292a0 326 name => 'bob',
76b8cf98 327 producer_to_cd => [
328 {
329 cd => {
330 artist => {
533292a0 331 name => 'lars',
04ec3909 332 cds => [
333 {
533292a0 334 title => 'Greatest hits 2',
04ec3909 335 year => 2012,
336 genre => {
337 name => '"Greatest" collections',
338 },
339 tags => [
340 { tag => 'A' },
341 { tag => 'B' },
342 ],
533292a0 343 # This cd is created via artist so it doesn't know about producers
344 cd_to_producer => [
345 # if we specify 'bob' here things bomb
346 # as the producer attached to Greatest Hits 1 is
347 # already created, but not yet inserted.
348 # Maybe this can be fixed, but things are hairy
349 # enough already.
350 #
351 #{ producer => { name => 'bob' } },
352 { producer => { name => 'paul' } },
353 { producer => {
354 name => 'flemming',
355 producer_to_cd => [
356 { cd => {
357 artist => {
358 name => 'kirk',
359 cds => [
360 {
361 title => 'Greatest hits 3',
362 year => 2012,
363 genre => {
364 name => '"Greatest" collections',
365 },
366 tags => [
367 { tag => 'A' },
368 { tag => 'B' },
369 ],
370 },
371 {
372 title => 'Greatest hits 4',
373 year => 2012,
374 genre => {
375 name => '"Greatest" collections2',
376 },
377 tags => [
378 { tag => 'A' },
379 { tag => 'B' },
380 ],
381 },
382 ],
383 },
384 title => 'Greatest hits 5',
385 year => 2013,
386 genre => {
387 name => '"Greatest" collections2',
388 },
389 }},
390 ],
391 }},
392 ],
04ec3909 393 },
394 ],
76b8cf98 395 },
533292a0 396 title => 'Greatest hits 6',
76b8cf98 397 year => 2012,
398 genre => {
399 name => '"Greatest" collections',
400 },
04ec3909 401 tags => [
402 { tag => 'A' },
403 { tag => 'B' },
404 ],
76b8cf98 405 },
406 },
407 {
408 cd => {
409 artist => {
533292a0 410 name => 'lars', # should already exist
411 # even though the artist 'name' is not uniquely constrained
412 # find_or_create will arguably DWIM
76b8cf98 413 },
533292a0 414 title => 'Greatest hits 7',
415 year => 2013,
76b8cf98 416 },
417 },
418 ],
419 },
420 },
421 ],
04ec3909 422 });
76b8cf98 423
533292a0 424 is ($schema->resultset ('Artist')->count, $counts->{Artist} + 3, '3 new artists created');
425 is ($schema->resultset ('Genre')->count, $counts->{Genre} + 2, '2 additional genres created');
426 is ($schema->resultset ('Producer')->count, $counts->{Producer} + 3, '3 new producer');
427 is ($schema->resultset ('CD')->count, $counts->{CD} + 7, '7 new CDs');
428 is ($schema->resultset ('Tag')->count, $counts->{Tag} + 10, '10 new Tags');
429
430 my $cd_rs = $schema->resultset ('CD')
431 ->search ({ title => { -like => 'Greatest hits %' }}, { order_by => 'title'} );
432 is ($cd_rs->count, 7, '7 greatest hits created');
433
434 my $cds_2012 = $cd_rs->search ({ year => 2012});
435 is ($cds_2012->count, 5, '5 CDs created in 2012');
436
437 is (
438 $cds_2012->search(
439 { 'tags.tag' => { -in => [qw/A B/] } },
440 { join => 'tags', group_by => 'me.cdid' }
441 ),
442 5,
c45f4e10 443 'All 10 tags were pairwise distributed between 5 year-2012 CDs'
533292a0 444 );
445
446 my $paul_prod = $cd_rs->search (
447 { 'producer.name' => 'paul'},
448 { join => { cd_to_producer => 'producer' } }
449 );
450 is ($paul_prod->count, 1, 'Paul had 1 production');
451 my $pauls_cd = $paul_prod->single;
452 is ($pauls_cd->cd_to_producer->count, 2, 'Paul had one co-producer');
453 is (
454 $pauls_cd->search_related ('cd_to_producer',
455 { 'producer.name' => 'flemming'},
456 { join => 'producer' }
457 )->count,
458 1,
459 'The second producer is flemming',
460 );
461
462 my $kirk_cds = $cd_rs->search ({ 'artist.name' => 'kirk' }, { join => 'artist' });
463 is ($kirk_cds, 3, 'Kirk had 3 CDs');
464 is (
465 $kirk_cds->search (
466 { 'cd_to_producer.cd' => { '!=', undef } },
467 { join => 'cd_to_producer' },
468 ),
469 1,
470 'Kirk had a producer only on one cd',
471 );
472
473 my $lars_cds = $cd_rs->search ({ 'artist.name' => 'lars' }, { join => 'artist' });
474 is ($lars_cds->count, 3, 'Lars had 3 CDs');
475 is (
476 $lars_cds->search (
477 { 'cd_to_producer.cd' => undef },
478 { join => 'cd_to_producer' },
479 ),
480 0,
481 'Lars always had a producer',
482 );
483 is (
484 $lars_cds->search_related ('cd_to_producer',
485 { 'producer.name' => 'flemming'},
486 { join => 'producer' }
487 )->count,
488 1,
489 'Lars produced 1 CD with flemming',
490 );
491 is (
492 $lars_cds->search_related ('cd_to_producer',
493 { 'producer.name' => 'bob'},
494 { join => 'producer' }
495 )->count,
496 2,
497 'Lars produced 2 CDs with bob',
498 );
499
500 my $bob_prod = $cd_rs->search (
501 { 'producer.name' => 'bob'},
502 { join => { cd_to_producer => 'producer' } }
503 );
504 is ($bob_prod->count, 3, 'Bob produced a total of 3 CDs');
505
506 is (
507 $bob_prod->search ({ 'artist.name' => 'james' }, { join => 'artist' })->count,
508 1,
c45f4e10 509 "Bob produced james' only CD",
533292a0 510 );
04ec3909 511};
512diag $@ if $@;