summaryrefslogtreecommitdiffstats
path: root/toolkit/components/places/tests/unit/test_tagging.js
blob: ccb28705023ee9f39c254bac5024684db0d256ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Notice we use createInstance because later we will have to terminate the
// service and restart it.
var tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
              createInstance().QueryInterface(Ci.nsITaggingService);

function run_test() {
  var options = PlacesUtils.history.getNewQueryOptions();
  var query = PlacesUtils.history.getNewQuery();

  query.setFolders([PlacesUtils.tagsFolderId], 1);
  var result = PlacesUtils.history.executeQuery(query, options);
  var tagRoot = result.root;
  tagRoot.containerOpen = true;

  do_check_eq(tagRoot.childCount, 0);

  var uri1 = uri("http://foo.tld/");
  var uri2 = uri("https://bar.tld/");

  // this also tests that the multiple folders are not created for the same tag
  tagssvc.tagURI(uri1, ["tag 1"]);
  tagssvc.tagURI(uri2, ["tag 1"]);
  do_check_eq(tagRoot.childCount, 1);

  var tag1node = tagRoot.getChild(0)
                        .QueryInterface(Ci.nsINavHistoryContainerResultNode);
  var tag1itemId = tag1node.itemId;

  do_check_eq(tag1node.title, "tag 1");
  tag1node.containerOpen = true;
  do_check_eq(tag1node.childCount, 2);

  // Tagging the same url twice (or even thrice!) with the same tag should be a
  // no-op
  tagssvc.tagURI(uri1, ["tag 1"]);
  do_check_eq(tag1node.childCount, 2);
  tagssvc.tagURI(uri1, [tag1itemId]);
  do_check_eq(tag1node.childCount, 2);
  do_check_eq(tagRoot.childCount, 1);

  // also tests bug 407575
  tagssvc.tagURI(uri1, [tag1itemId, "tag 1", "tag 2", "Tag 1", "Tag 2"]);
  do_check_eq(tagRoot.childCount, 2);
  do_check_eq(tag1node.childCount, 2);

  // test getTagsForURI
  var uri1tags = tagssvc.getTagsForURI(uri1);
  do_check_eq(uri1tags.length, 2);
  do_check_eq(uri1tags[0], "Tag 1");
  do_check_eq(uri1tags[1], "Tag 2");
  var uri2tags = tagssvc.getTagsForURI(uri2);
  do_check_eq(uri2tags.length, 1);
  do_check_eq(uri2tags[0], "Tag 1");

  // test getURIsForTag
  var tag1uris = tagssvc.getURIsForTag("tag 1");
  do_check_eq(tag1uris.length, 2);
  do_check_true(tag1uris[0].equals(uri1));
  do_check_true(tag1uris[1].equals(uri2));

  // test allTags attribute
  var allTags = tagssvc.allTags;
  do_check_eq(allTags.length, 2);
  do_check_eq(allTags[0], "Tag 1");
  do_check_eq(allTags[1], "Tag 2");

  // test untagging
  tagssvc.untagURI(uri1, ["tag 1"]);
  do_check_eq(tag1node.childCount, 1);

  // removing the last uri from a tag should remove the tag-container
  tagssvc.untagURI(uri2, ["tag 1"]);
  do_check_eq(tagRoot.childCount, 1);

  // cleanup
  tag1node.containerOpen = false;

  // get array of tag folder ids => title
  // for testing tagging with mixed folder ids and tags
  var child = tagRoot.getChild(0);
  var tagId = child.itemId;
  var tagTitle = child.title;

  // test mixed id/name tagging
  // as well as non-id numeric tags
  var uri3 = uri("http://testuri/3");
  tagssvc.tagURI(uri3, [tagId, "tag 3", "456"]);
  var tags = tagssvc.getTagsForURI(uri3);
  do_check_true(tags.includes(tagTitle));
  do_check_true(tags.includes("tag 3"));
  do_check_true(tags.includes("456"));

  // test mixed id/name tagging
  tagssvc.untagURI(uri3, [tagId, "tag 3", "456"]);
  tags = tagssvc.getTagsForURI(uri3);
  do_check_eq(tags.length, 0);

  // Terminate tagging service, fire up a new instance and check that existing
  // tags are there.  This will ensure that any internal caching system is
  // correctly filled at startup and we are not losing previously existing tags.
  var uri4 = uri("http://testuri/4");
  tagssvc.tagURI(uri4, [tagId, "tag 3", "456"]);
  tagssvc = null;
  tagssvc = Cc["@mozilla.org/browser/tagging-service;1"].
            getService(Ci.nsITaggingService);
  var uri4Tags = tagssvc.getTagsForURI(uri4);
  do_check_eq(uri4Tags.length, 3);
  do_check_true(uri4Tags.includes(tagTitle));
  do_check_true(uri4Tags.includes("tag 3"));
  do_check_true(uri4Tags.includes("456"));

  // Test sparse arrays.
  let curChildCount = tagRoot.childCount;

  try {
    tagssvc.tagURI(uri1, [, "tagSparse"]);
    do_check_eq(tagRoot.childCount, curChildCount + 1);
  } catch (ex) {
    do_throw("Passing a sparse array should not throw");
  }
  try {
    tagssvc.untagURI(uri1, [, "tagSparse"]);
    do_check_eq(tagRoot.childCount, curChildCount);
  } catch (ex) {
    do_throw("Passing a sparse array should not throw");
  }

  // Test that the API throws for bad arguments.
  try {
    tagssvc.tagURI(uri1, ["", "test"]);
    do_throw("Passing a bad tags array should throw");
  } catch (ex) {
    do_check_eq(ex.name, "NS_ERROR_ILLEGAL_VALUE");
  }
  try {
    tagssvc.untagURI(uri1, ["", "test"]);
    do_throw("Passing a bad tags array should throw");
  } catch (ex) {
    do_check_eq(ex.name, "NS_ERROR_ILLEGAL_VALUE");
  }
  try {
    tagssvc.tagURI(uri1, [0, "test"]);
    do_throw("Passing a bad tags array should throw");
  } catch (ex) {
    do_check_eq(ex.name, "NS_ERROR_ILLEGAL_VALUE");
  }
  try {
    tagssvc.tagURI(uri1, [0, "test"]);
    do_throw("Passing a bad tags array should throw");
  } catch (ex) {
    do_check_eq(ex.name, "NS_ERROR_ILLEGAL_VALUE");
  }

  // Tag name length should be limited to nsITaggingService.MAX_TAG_LENGTH (bug407821)
  try {

    // generate a long tag name. i.e. looooo...oong_tag
    var n = Ci.nsITaggingService.MAX_TAG_LENGTH;
    var someOos = new Array(n).join('o');
    var longTagName = "l" + someOos + "ng_tag";

    tagssvc.tagURI(uri1, ["short_tag", longTagName]);
    do_throw("Passing a bad tags array should throw");

  } catch (ex) {
    do_check_eq(ex.name, "NS_ERROR_ILLEGAL_VALUE");
  }

  // cleanup
  tagRoot.containerOpen = false;

  // Tagging service should trim tags (Bug967196)
  let exampleURI = uri("http://www.example.com/");
  PlacesUtils.tagging.tagURI(exampleURI, [ " test " ]);

  let exampleTags = PlacesUtils.tagging.getTagsForURI(exampleURI);
  do_check_eq(exampleTags.length, 1);
  do_check_eq(exampleTags[0], "test");

  PlacesUtils.tagging.untagURI(exampleURI, [ "test" ]);
  exampleTags = PlacesUtils.tagging.getTagsForURI(exampleURI);
  do_check_eq(exampleTags.length, 0);
}