fix has_tags([$names]) and add has_tag($name)/has_tag($tag_object)
[bse.git] / t / 050-local / 030-tags.t
CommitLineData
b6a28bd1
TC
1#!perl -w
2use strict;
3use BSE::Test ();
da19080c 4use Test::More tests => 51;
b6a28bd1
TC
5use File::Spec;
6use Carp qw(confess);
7
8$SIG{__DIE__} = sub { confess @_ };
9
10BEGIN {
11 unshift @INC, File::Spec->catdir(BSE::Test::base_dir(), "cgi-bin", "modules");
12}
13
14use BSE::API ':all';
15
16my $base_cgi = File::Spec->catdir(BSE::Test::base_dir(), "cgi-bin");
17ok(bse_init($base_cgi), "initialize api")
18 or print "# failed to bse_init in $base_cgi\n";
19my $cfg = bse_cfg;
20
21# set up some test data
22my $parent = bse_make_catalog(title => "Tags parent",
23 cfg => $cfg);
24ok($parent, "make parent article");
25my @kids;
26my %kids;
27for my $title ("A" .. "Z") {
28 my $kid = bse_make_product
29 (
30 cfg => $cfg,
31 title => $title,
32 retailPrice => 0,
33 parentid => $parent->id
34 );
35 push @kids, $kid;
36 $kids{$title} = $kid;
37}
38
39{
40 my %tags =
41 (
42 A => "Platform: iPad/iPad: iPad 1",
43 B => "Platform: iPad/iPad: iPad 1",
44 C => "Platform: iPad/iPad: iPad 2",
45 D => "Platform: iPad/iPad: iPad 2",
46 E => "Platform: iPad/iPad: iPad 2",
47 F => "Platform: iPad/iPad: iPad 3",
48 G => "Platform: iPod/iPod: Classic",
49 H => "Platform: iPod/iPod: Classic",
50 I => "Platform: iPod/iPod: Nano",
51 J => "Platform: iPod/iPod: Nano",
52 K => "Platform: iPod/iPod: 6th Gen",
53 L => "Platform: iPod/iPod: 6th Gen",
54 M => "Platform: iPhone/iPhone: 3G",
55 N => "Platform: iPhone/iPhone: 3G",
56 O => "Platform: iPhone/iPhone: 3GS",
57 P => "Platform: iPhone/iPhone: 4",
58 Q => "Platform: iPhone/iPhone: 4",
59 );
60
61 # set the tags
62 my $all_set = 1;
63 for my $title (keys %tags) {
64 my $kid = $kids{$title} or die "No kid $title found";
65 my $error;
66 unless ($kid->set_tags([ split '/', $tags{$title} ], \$error)) {
67 diag "Setting $title tags: $error\n";
68 $all_set = 0;
69 }
70 }
71 ok($all_set, "all kid tags set");
72}
73
60a62554
TC
74{
75 my @tags = $kids[0]->tag_objects;
76 my @ids = sort map $_->id, @tags;
77 is_deeply([ sort $kids[0]->tag_ids ], \@ids, "check tag_ids works");
78}
79
80{
ab004bbb 81 my $tag_info = BSE::TB::Products->collection_with_tags
60a62554
TC
82 (
83 "all_visible_products",
84 [ "iPod: Nano" ],
85 { args => [ $parent->id ] },
86 );
87 my @expect = map $_->id, sort { $a->id <=> $b->id } @kids{"I", "J"};
88 my @found = map $_->id, sort { $a->id <=> $b->id } @{$tag_info->{objects}};
89 is_deeply(\@found, \@expect, "collection with tags on all_visible_products");
90}
91
b6a28bd1
TC
92is_deeply([ map $_->title, $parent->children ],
93 [ reverse("A" .. "Z") ],
94 "check the childrent are in place");
95
96{
97 ok(!$parent->can("children_tags"), "non-optimized path");
98 my $tagged = $parent->collection_with_tags
99 (
100 "children",
101 [ "Platform: iPad" ]
102 );
103 ok($tagged, "collection_with_tags returned");
104 SKIP:
105 {
106 ok($tagged->{objects}, "has objects")
107 or skip("No objects", 1);
108 is_deeply([ map $_->title, @{$tagged->{objects}} ],
109 [ reverse("A" .. "F") ],
110 "check we got the expected kids");
111 }
112 SKIP:
113 {
114 ok($tagged->{object_ids}, "has object_ids")
115 or skip("No object_ids", 1);
116 is_deeply($tagged->{object_ids},
117 [ map $_->id, @kids{reverse("A" .. "F")} ],
118 "check object_ids");
119 }
120 SKIP:
121 {
122 ok($tagged->{extratags}, "has extratags")
123 or skip("No extratags", 1);
124 is(join("/", sort map $_->name, @{$tagged->{extratags}}),
125 "iPad: iPad 1/iPad: iPad 2/iPad: iPad 3",
126 "check knowntags");
127 }
128 ok($tagged->{members}, "has members");
129 SKIP:
130 {
131 ok($tagged->{counts}, "has counts")
132 or skip("No counts", 1);
133 is_deeply($tagged->{counts},
134 {
135 "iPad: iPad 1" => 2,
136 "iPad: iPad 2" => 3,
137 "iPad: iPad 3" => 1,
138 }, "check counts");
139 }
140}
141
142{
143 ok($parent->can("all_visible_product_tags"), "optimized path");
144 my $tagged = $parent->collection_with_tags
145 (
146 "all_visible_products",
147 [ "Platform: iPad" ]
148 );
149 ok($tagged, "collection_with_tags returned (all_visible_products)");
150 SKIP:
151 {
152 ok($tagged->{objects}, "has objects")
153 or skip("No objects", 1);
154 is_deeply([ map $_->title, @{$tagged->{objects}} ],
155 [ reverse("A" .. "F") ],
156 "check we got the expected kids");
157 }
158 SKIP:
159 {
160 ok($tagged->{object_ids}, "has object_ids")
161 or skip("No object_ids", 1);
162 is_deeply($tagged->{object_ids},
163 [ map $_->id, @kids{reverse("A" .. "F")} ],
164 "check object_ids");
165 }
166 SKIP:
167 {
168 ok($tagged->{extratags}, "has extratags")
169 or skip("No extratags", 1);
170 is(join("/", sort map $_->name, @{$tagged->{extratags}}),
171 "iPad: iPad 1/iPad: iPad 2/iPad: iPad 3",
172 "check knowntags");
173 }
174 ok($tagged->{members}, "has members");
175 SKIP:
176 {
177 ok($tagged->{counts}, "has counts")
178 or skip("No counts", 1);
179 is_deeply($tagged->{counts},
180 {
181 "iPad: iPad 1" => 2,
182 "iPad: iPad 2" => 3,
183 "iPad: iPad 3" => 1,
184 }, "check counts");
185 }
186}
187
188{
189 ok($parent->can("all_visible_product_tags"), "optimized path");
190 my $tagged = $parent->collection_with_tags
191 (
192 "all_visible_products",
193 [ "Platform: iPad" ],
194 { noobjects => 1 }
195 );
196 ok($tagged, "collection_with_tags returned (all_visible_products, no objects)");
197 ok(!$tagged->{objects}, "no objects");
198 SKIP:
199 {
200 ok($tagged->{object_ids}, "has object_ids")
201 or skip("No object_ids", 1);
202 # they don't necessarily come back in order
203 is_deeply([ sort @{$tagged->{object_ids}} ],
204 [ sort map $_->id, @kids{reverse("A" .. "F")} ],
205 "check object_ids");
206 }
207 SKIP:
208 {
209 ok($tagged->{extratags}, "has extratags")
210 or skip("No extratags", 1);
211 is(join("/", sort map $_->name, @{$tagged->{extratags}}),
212 "iPad: iPad 1/iPad: iPad 2/iPad: iPad 3",
213 "check knowntags");
214 }
215 ok($tagged->{members}, "has members");
216 SKIP:
217 {
218 ok($tagged->{counts}, "has counts")
219 or skip("No counts", 1);
220 is_deeply($tagged->{counts},
221 {
222 "iPad: iPad 1" => 2,
223 "iPad: iPad 2" => 3,
224 "iPad: iPad 3" => 1,
225 }, "check counts");
226 }
227}
228
da19080c
TC
229{
230 my $error;
231 ok($parent->set_tags([ "SomeTag" ], \$error), "add SomeTag to parent");
232 ok($parent->has_tags([ "SomeTag" ]), "check true has_tags() by name");
233 my ($tag) = $parent->tag_objects;
234 is($tag->name, "SomeTag", "check tag_objects tag");
235 ok($parent->has_tags([ $tag ]), "check true has_tags() by object");
236 ok(!$parent->has_tags([ "Platform: iPad" ]), "check false has_tags() by name");
237 my $unknown = "Unknown: " . time();
238 ok(!$parent->has_tags([ $unknown ]),
239 "check false has_tags() by name (unknown tag)");
240 is_deeply([ $parent->tags ], [ "SomeTag" ], "tags() method");
241 my ($tag_id) = $parent->tag_ids;
242 is($tag_id, $tag->id, "check tag_ids");
243 my $by_name = $parent->tag_by_name("SomeTag");
244 is($by_name->id, $tag->id, "check tag_by_name()");
245 ok($parent->has_tag("SomeTag"), "check true has_tag() by name");
246 ok($parent->has_tag($tag), "check true has_tag() by object");
247 ok(!$parent->has_tag("Platform: iPad"), "check false has_tag() by name");
248 ok(!$parent->has_tag($unknown),
249 "check false has_tag() by name (unknown tag)");
250}
251
b6a28bd1
TC
252END {
253 for my $kid (@kids) {
254 $kid->remove($cfg);
255 }
256 $parent->remove($cfg) if $parent;
257}