Search

Personas in this Story: Default, FinancialManager, Member, Client.

For the purpose of this test, we have a couple of users (owner, financial manager, regular member and a client) and a client company:

Response: HTTP 200, application/json (Hide)
GET /users

Response:

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
[
    {
        "id": 1,
        "class": "Owner",
        "url_path": "\/users\/1",
        "is_archived": false,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164728,
        "created_by_id": 1,
        "updated_on": 1430164728,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "Ilija.studen",
        "last_name": null,
        "display_name": "ilija.studen",
        "short_display_name": "ilija.studen",
        "email": "ilija.studen@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": false,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=1&size=--SIZE--&timestamp=1430164728",
        "custom_permissions": [],
        "company_id": 1,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    },
    {
        "id": 2,
        "class": "Member",
        "url_path": "\/users\/2",
        "is_archived": false,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164731,
        "created_by_id": 1,
        "updated_on": 1430164731,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "Financial.manager",
        "last_name": null,
        "display_name": "financial.manager",
        "short_display_name": "financial.manager",
        "email": "financial.manager@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": false,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=2&size=--SIZE--&timestamp=1430164731",
        "custom_permissions": [
            "can_manage_finances"
        ],
        "company_id": 0,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    },
    {
        "id": 3,
        "class": "Member",
        "url_path": "\/users\/3",
        "is_archived": false,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164731,
        "created_by_id": 1,
        "updated_on": 1430164731,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "Regular.member",
        "last_name": null,
        "display_name": "regular.member",
        "short_display_name": "regular.member",
        "email": "regular.member@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": false,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=3&size=--SIZE--&timestamp=1430164731",
        "custom_permissions": [],
        "company_id": 0,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    },
    {
        "id": 4,
        "class": "Client",
        "url_path": "\/users\/4",
        "is_archived": false,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "created_on": 1430164731,
        "created_by_id": 1,
        "updated_on": 1430164731,
        "updated_by_id": 1,
        "language_id": 0,
        "first_name": "Client1",
        "last_name": null,
        "display_name": "client1",
        "short_display_name": "client1",
        "email": "client1@activecollab.com",
        "additional_email_addresses": [],
        "is_pending_activation": false,
        "avatar_url": "http:\/\/feather.dev\/proxy.php?proxy=avatar&module=system&v=current&b=DEV&user_id=4&size=--SIZE--&timestamp=1430164731",
        "custom_permissions": [],
        "company_id": 2,
        "title": null,
        "phone": null,
        "im_type": null,
        "im_handle": null,
        "note": null
    }
]
Response: HTTP 200, application/json (Hide)
GET /companies/2

Response:

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
{
    "single": {
        "id": 2,
        "class": "Company",
        "url_path": "\/companies\/2",
        "name": "ACME Inc",
        "members": [
            4
        ],
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "is_archived": false,
        "created_on": 1430164731,
        "created_by_id": 1,
        "updated_on": 1430164731,
        "updated_by_id": 1,
        "address": "Street Name 12\nCity",
        "phone": null,
        "homepage_url": null,
        "tax_id": null,
        "currency_id": 1,
        "is_owner": false,
        "has_note": false
    },
    "hourly_rates": {
        "1": 100
    },
    "active_projects_count": 0
}

Lets create an estimate:

Response: HTTP 200, application/json (Hide)
POST /estimates

Payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
    "company_id": 2,
    "name": "Books",
    "items": [
        {
            "description": "Managing Humans: Biting and Humorous Tales of a Software Engineering Manager",
            "quantity": 1,
            "unit_cost": 17.91
        },
        {
            "description": "Hyperion (Hyperion Cantos)",
            "quantity": 1,
            "unit_cost": 4.83
        },
        {
            "description": "I'm Feeling Lucky: The Confessions of Google Employee Number 59",
            "quantity": 1,
            "unit_cost": 6.38
        }
    ],
    "private_note": "Comlog, a rare term used in the private note"
}

Response:

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
{
    "single": {
        "id": 1,
        "class": "Estimate",
        "url_path": "\/estimates\/1",
        "name": "Books",
        "comments_count": 0,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "company_id": 2,
        "company_name": "ACME Inc",
        "company_address": "Street Name 12\nCity",
        "note": null,
        "currency_id": 1,
        "language_id": 0,
        "discount_rate": 0,
        "subtotal": 29.12,
        "subtotal_without_discount": 29.12,
        "discount": 0,
        "tax": 0,
        "rounding_difference": 0,
        "rounded_total": 29.12,
        "total": 29.12,
        "paid_amount": 0,
        "balance_due": 29.12,
        "recipients": null,
        "email_from": null,
        "email_subject": null,
        "email_body": null,
        "second_tax_is_enabled": false,
        "second_tax_is_compound": false,
        "created_on": 1430164732,
        "created_by_id": 1,
        "updated_on": 1430164732,
        "hash": "fdrBZ4CZDbAxIPGyR7vgVmVoVzemUCZZFgqt0TiC",
        "status": "draft",
        "public_url": "#"
    },
    "subscribers": [
        1
    ],
    "comments": [],
    "items": [
        {
            "id": 1,
            "class": "InvoiceItem",
            "url_path": "\/invoice-items\/1",
            "parent_type": "Estimate",
            "parent_id": 1,
            "discount_rate": 0,
            "description": "Managing Humans: Biting and Humorous Tales of a Software Engineering Manager",
            "quantity": 1,
            "unit_cost": 17.91,
            "first_tax_rate_id": 0,
            "first_tax_value": 0,
            "first_tax_name": "",
            "first_tax_rate": 0,
            "second_tax_rate_id": 0,
            "second_tax_value": 0,
            "second_tax_name": "",
            "second_tax_rate": 0,
            "second_tax_is_enabled": false,
            "second_tax_is_compound": false,
            "subtotal": 17.91,
            "subtotal_without_discount": 17.91,
            "discount": 0,
            "total": 17.91,
            "position": 1
        },
        {
            "id": 2,
            "class": "InvoiceItem",
            "url_path": "\/invoice-items\/2",
            "parent_type": "Estimate",
            "parent_id": 1,
            "discount_rate": 0,
            "description": "Hyperion (Hyperion Cantos)",
            "quantity": 1,
            "unit_cost": 4.83,
            "first_tax_rate_id": 0,
            "first_tax_value": 0,
            "first_tax_name": "",
            "first_tax_rate": 0,
            "second_tax_rate_id": 0,
            "second_tax_value": 0,
            "second_tax_name": "",
            "second_tax_rate": 0,
            "second_tax_is_enabled": false,
            "second_tax_is_compound": false,
            "subtotal": 4.83,
            "subtotal_without_discount": 4.83,
            "discount": 0,
            "total": 4.83,
            "position": 2
        },
        {
            "id": 3,
            "class": "InvoiceItem",
            "url_path": "\/invoice-items\/3",
            "parent_type": "Estimate",
            "parent_id": 1,
            "discount_rate": 0,
            "description": "I'm Feeling Lucky: The Confessions of Google Employee Number 59",
            "quantity": 1,
            "unit_cost": 6.38,
            "first_tax_rate_id": 0,
            "first_tax_value": 0,
            "first_tax_name": "",
            "first_tax_rate": 0,
            "second_tax_rate_id": 0,
            "second_tax_value": 0,
            "second_tax_name": "",
            "second_tax_rate": 0,
            "second_tax_is_enabled": false,
            "second_tax_is_compound": false,
            "subtotal": 6.38,
            "subtotal_without_discount": 6.38,
            "discount": 0,
            "total": 6.38,
            "position": 3
        }
    ]
}

Search should return the estimate when serched for client details:

Response: HTTP 200, application/json (Hide)
GET /search?q=ACME

Response:

1
[]

or name:

Response: HTTP 200, application/json (Hide)
GET /search?q=ACME

Response:

1
[]

A term from the notes:

Response: HTTP 200, application/json (Hide)
GET /search?q=books

Response:

1
[]

Or a term from the items:

Response: HTTP 200, application/json (Hide)
GET /search?q=hyperion

Response:

1
[]

Financial manager will also be able to find this estimate using the search:

Response: HTTP 200, application/json (Hide)
GET /search?q=hyperion (as FinancialManager)

Response:

1
[]

but member (who does not have permissions to manage finances) and client will not be able to access it:

Response: HTTP 200, application/json (Hide)
GET /search?q=hyperion (as Member)

Response:

1
[]
Response: HTTP 200, application/json (Hide)
GET /search?q=hyperion (as Client)

Response:

1
[]

By mistake, we added the wrong book to the estimate. Here are corrections:

Response: HTTP 200, application/json (Hide)
PUT /estimates/1

Payload:

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
{
    "items": [
        {
            "id": 1,
            "description": "Managing Humans: Biting and Humorous Tales of a Software Engineering Manager",
            "quantity": 1,
            "unit_cost": 17.91
        },
        {
            "id": 2,
            "description": "The Rise of Endymion (Hyperion)",
            "quantity": 1,
            "unit_cost": 7.19
        },
        {
            "id": 3,
            "description": "I'm Feeling Lucky: The Confessions of Google Employee Number 59",
            "quantity": 1,
            "unit_cost": 6.38
        },
        {
            "description": "Endymion (Hyperion Cantos, Bk. 3)",
            "quantity": 1,
            "unit_cost": 7.19
        }
    ]
}

Response:

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
{
    "single": {
        "id": 1,
        "class": "Estimate",
        "url_path": "\/estimates\/1",
        "name": "Books",
        "comments_count": 0,
        "is_trashed": false,
        "trashed_on": null,
        "trashed_by_id": 0,
        "company_id": 2,
        "company_name": "ACME Inc",
        "company_address": "Street Name 12\nCity",
        "note": null,
        "currency_id": 1,
        "language_id": 0,
        "discount_rate": 0,
        "subtotal": 38.67,
        "subtotal_without_discount": 38.67,
        "discount": 0,
        "tax": 0,
        "rounding_difference": 0,
        "rounded_total": 38.67,
        "total": 38.67,
        "paid_amount": 0,
        "balance_due": 38.67,
        "recipients": null,
        "email_from": null,
        "email_subject": null,
        "email_body": null,
        "second_tax_is_enabled": false,
        "second_tax_is_compound": false,
        "created_on": 1430164732,
        "created_by_id": 1,
        "updated_on": 1430164733,
        "hash": "fdrBZ4CZDbAxIPGyR7vgVmVoVzemUCZZFgqt0TiC",
        "status": "draft",
        "public_url": "#"
    },
    "subscribers": [
        1
    ],
    "comments": [],
    "items": [
        {
            "id": 1,
            "class": "InvoiceItem",
            "url_path": "\/invoice-items\/1",
            "parent_type": "Estimate",
            "parent_id": 1,
            "discount_rate": 0,
            "description": "Managing Humans: Biting and Humorous Tales of a Software Engineering Manager",
            "quantity": 1,
            "unit_cost": 17.91,
            "first_tax_rate_id": 0,
            "first_tax_value": 0,
            "first_tax_name": "",
            "first_tax_rate": 0,
            "second_tax_rate_id": 0,
            "second_tax_value": 0,
            "second_tax_name": "",
            "second_tax_rate": 0,
            "second_tax_is_enabled": false,
            "second_tax_is_compound": false,
            "subtotal": 17.91,
            "subtotal_without_discount": 17.91,
            "discount": 0,
            "total": 17.91,
            "position": 1
        },
        {
            "id": 2,
            "class": "InvoiceItem",
            "url_path": "\/invoice-items\/2",
            "parent_type": "Estimate",
            "parent_id": 1,
            "discount_rate": 0,
            "description": "The Rise of Endymion (Hyperion)",
            "quantity": 1,
            "unit_cost": 7.19,
            "first_tax_rate_id": 0,
            "first_tax_value": 0,
            "first_tax_name": "",
            "first_tax_rate": 0,
            "second_tax_rate_id": 0,
            "second_tax_value": 0,
            "second_tax_name": "",
            "second_tax_rate": 0,
            "second_tax_is_enabled": false,
            "second_tax_is_compound": false,
            "subtotal": 7.19,
            "subtotal_without_discount": 7.19,
            "discount": 0,
            "total": 7.19,
            "position": 2
        },
        {
            "id": 3,
            "class": "InvoiceItem",
            "url_path": "\/invoice-items\/3",
            "parent_type": "Estimate",
            "parent_id": 1,
            "discount_rate": 0,
            "description": "I'm Feeling Lucky: The Confessions of Google Employee Number 59",
            "quantity": 1,
            "unit_cost": 6.38,
            "first_tax_rate_id": 0,
            "first_tax_value": 0,
            "first_tax_name": "",
            "first_tax_rate": 0,
            "second_tax_rate_id": 0,
            "second_tax_value": 0,
            "second_tax_name": "",
            "second_tax_rate": 0,
            "second_tax_is_enabled": false,
            "second_tax_is_compound": false,
            "subtotal": 6.38,
            "subtotal_without_discount": 6.38,
            "discount": 0,
            "total": 6.38,
            "position": 3
        },
        {
            "id": 4,
            "class": "InvoiceItem",
            "url_path": "\/invoice-items\/4",
            "parent_type": "Estimate",
            "parent_id": 1,
            "discount_rate": 0,
            "description": "Endymion (Hyperion Cantos, Bk. 3)",
            "quantity": 1,
            "unit_cost": 7.19,
            "first_tax_rate_id": 0,
            "first_tax_value": 0,
            "first_tax_name": "",
            "first_tax_rate": 0,
            "second_tax_rate_id": 0,
            "second_tax_value": 0,
            "second_tax_name": "",
            "second_tax_rate": 0,
            "second_tax_is_enabled": false,
            "second_tax_is_compound": false,
            "subtotal": 7.19,
            "subtotal_without_discount": 7.19,
            "discount": 0,
            "total": 7.19,
            "position": 4
        }
    ]
}

Search index should work just fine even after this update, even for terms that we just added:

Response: HTTP 200, application/json (Hide)
GET /search?q=endymion

Response:

1
[]