1 //------------------------------------------------------------------------------ 2 // FindAppTester.cpp 3 // 4 //------------------------------------------------------------------------------ 5 6 // Standard Includes ----------------------------------------------------------- 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <utime.h> 10 11 // System Includes ------------------------------------------------------------- 12 #include <Message.h> 13 #include <OS.h> 14 #include <AppFileInfo.h> 15 #include <Application.h> 16 #include <File.h> 17 #include <FindDirectory.h> 18 #include <Handler.h> 19 #include <Looper.h> 20 #include <Path.h> 21 #include <Roster.h> 22 #include <String.h> 23 24 // Project Includes ------------------------------------------------------------ 25 #include <TestShell.h> 26 #include <TestUtils.h> 27 #include <cppunit/TestAssert.h> 28 29 // Local Includes -------------------------------------------------------------- 30 #include "AppRunner.h" 31 #include "FindAppTester.h" 32 33 // Local Defines --------------------------------------------------------------- 34 35 // Globals --------------------------------------------------------------------- 36 37 //------------------------------------------------------------------------------ 38 39 static const char *uninstalledType 40 = "application/x-vnd.obos-roster-findapp-uninstalled"; 41 static const char *appType1 = "application/x-vnd.obos-roster-findapp-app1"; 42 static const char *appType2 = "application/x-vnd.obos-roster-findapp-app2"; 43 static const char *fileType1 = "application/x-vnd.obos-roster-findapp-file1"; 44 static const char *fileType2 = "application/x-vnd.obos-roster-findapp-file2"; 45 static const char *textTestType = "text/x-vnd.obos-roster-findapp"; 46 47 static const char *testDir = "/tmp/testdir"; 48 static const char *appFile1 = "/tmp/testdir/app1"; 49 static const char *appFile2 = "/tmp/testdir/app2"; 50 static const char *testFile1 = "/tmp/testdir/testFile1"; 51 static const char *testLink1 = "/tmp/testdir/testLink1"; 52 static const char *trashAppName = "roster-findapp-app"; 53 54 // get_trash_app_file 55 static 56 const char* 57 get_trash_app_file() 58 { 59 static char trashAppFile[B_PATH_NAME_LENGTH]; 60 static bool initialized = false; 61 if (!initialized) { 62 BPath path; 63 CHK(find_directory(B_TRASH_DIRECTORY, &path) == B_OK); 64 CHK(path.Append(trashAppName) == B_OK); 65 strcpy(trashAppFile, path.Path()); 66 initialized = true; 67 } 68 return trashAppFile; 69 } 70 71 // install_type 72 static 73 void 74 install_type(const char *type, const char *preferredApp = NULL, 75 const char *snifferRule = NULL) 76 { 77 BMimeType mimeType(type); 78 if (!mimeType.IsInstalled()) 79 CHK(mimeType.Install() == B_OK); 80 if (preferredApp) 81 CHK(mimeType.SetPreferredApp(preferredApp) == B_OK); 82 if (snifferRule) 83 CHK(mimeType.SetSnifferRule(snifferRule) == B_OK); 84 } 85 86 // ref_for_path 87 static 88 entry_ref 89 ref_for_path(const char *filename, bool traverse = true) 90 { 91 entry_ref ref; 92 BEntry entry; 93 CHK(entry.SetTo(filename, traverse) == B_OK); 94 CHK(entry.GetRef(&ref) == B_OK); 95 return ref; 96 } 97 98 // create_app 99 static 100 void 101 create_app(const char *filename, const char *signature = NULL, 102 bool install = false, bool makeExecutable = true) 103 { 104 system((string("touch ") + filename).c_str()); 105 if (makeExecutable) 106 system((string("chmod a+x ") + filename).c_str()); 107 if (signature) { 108 BFile file; 109 CHK(file.SetTo(filename, B_READ_WRITE) == B_OK); 110 BAppFileInfo appFileInfo; 111 CHK(appFileInfo.SetTo(&file) == B_OK); 112 CHK(appFileInfo.SetSignature(signature) == B_OK); 113 if (install) 114 CHK(BMimeType(signature).Install() == B_OK); 115 } 116 } 117 118 // create_file 119 static 120 entry_ref 121 create_file(const char *filename, const char *type, 122 const char *preferredApp = NULL, const char *appHintPath = NULL, 123 const char *contents = NULL) 124 { 125 if (contents) 126 system((string("echo -n \"") + contents + "\" > " + filename).c_str()); 127 else 128 system((string("touch ") + filename).c_str()); 129 if (type || preferredApp || appHintPath) { 130 BFile file; 131 CHK(file.SetTo(filename, B_READ_WRITE) == B_OK); 132 BNodeInfo nodeInfo; 133 CHK(nodeInfo.SetTo(&file) == B_OK); 134 if (type) 135 CHK(nodeInfo.SetType(type) == B_OK); 136 if (preferredApp) 137 CHK(nodeInfo.SetPreferredApp(preferredApp) == B_OK); 138 if (appHintPath) { 139 entry_ref appHint(ref_for_path(appHintPath)); 140 CHK(nodeInfo.SetAppHint(&appHint) == B_OK); 141 } 142 } 143 return ref_for_path(filename); 144 } 145 146 // check_app_type 147 static 148 void 149 check_app_type(const char *signature, const char *filename) 150 { 151 BMimeType type(signature); 152 CHK(type.IsInstalled() == true); 153 if (filename) { 154 entry_ref appHint; 155 CHK(type.GetAppHint(&appHint) == B_OK); 156 CHK(ref_for_path(filename) == appHint); 157 } 158 } 159 160 // set_file_time 161 static 162 void 163 set_file_time(const char *filename, time_t time) 164 { 165 utimbuf buffer; 166 buffer.actime = time; 167 buffer.modtime = time; 168 CHK(utime(filename, &buffer) == 0); 169 } 170 171 // set_version 172 static 173 void 174 set_version(const char *filename, uint32 version) 175 { 176 version_info versionInfo = { 1, 1, 1, 1, version, "short1", "long1" }; 177 BFile file; 178 CHK(file.SetTo(filename, B_READ_WRITE) == B_OK); 179 BAppFileInfo appFileInfo; 180 CHK(appFileInfo.SetTo(&file) == B_OK); 181 CHK(appFileInfo.SetVersionInfo(&versionInfo, B_APP_VERSION_KIND) == B_OK); 182 } 183 184 // set_type_app_hint 185 static 186 void 187 set_type_app_hint(const char *signature, const char *filename) 188 { 189 BMimeType type(signature); 190 if (!type.IsInstalled()); 191 CHK(type.Install() == B_OK); 192 entry_ref fileRef(ref_for_path(filename)); 193 CHK(type.SetAppHint(&fileRef) == B_OK); 194 } 195 196 // setUp 197 void 198 FindAppTester::setUp() 199 { 200 fApplication = new BApplication("application/x-vnd.obos-roster-findapp"); 201 system((string("mkdir ") + testDir).c_str()); 202 } 203 204 // tearDown 205 void 206 FindAppTester::tearDown() 207 { 208 BMimeType(uninstalledType).Delete(); 209 BMimeType(appType1).Delete(); 210 BMimeType(appType2).Delete(); 211 BMimeType(fileType1).Delete(); 212 BMimeType(fileType2).Delete(); 213 BMimeType(textTestType).Delete(); 214 delete fApplication; 215 system((string("rm -rf ") + testDir).c_str()); 216 system((string("rm -f ") + get_trash_app_file()).c_str()); 217 } 218 219 // FindAppCaller 220 class FindAppCaller { 221 public: 222 virtual status_t operator()(const char *type, entry_ref *ref) = 0; 223 }; 224 225 /* 226 @case 1 uninstalled type mimeType 227 @results Should return B_LAUNCH_FAILED_APP_NOT_FOUND. 228 */ 229 static 230 void 231 CommonFindAppTest1(FindAppCaller &caller) 232 { 233 BRoster roster; 234 entry_ref ref; 235 CHK(caller(uninstalledType, &ref) == B_LAUNCH_FAILED_APP_NOT_FOUND); 236 } 237 238 /* 239 @case 2 installed type mimeType, no preferred app 240 @results Should return B_LAUNCH_FAILED_NO_PREFERRED_APP. 241 */ 242 static 243 void 244 CommonFindAppTest2(FindAppCaller &caller) 245 { 246 BRoster roster; 247 install_type(fileType1); 248 entry_ref ref; 249 CHK(caller(fileType1, &ref) == B_LAUNCH_FAILED_NO_PREFERRED_APP); 250 } 251 252 /* 253 @case 3 installed type mimeType, preferred app, app type not 254 installed, app has no signature 255 @results Should return B_LAUNCH_FAILED_APP_NOT_FOUND. 256 */ 257 static 258 void 259 CommonFindAppTest3(FindAppCaller &caller) 260 { 261 BRoster roster; 262 install_type(fileType1, appType1); 263 entry_ref ref; 264 CHK(caller(fileType1, &ref) == B_LAUNCH_FAILED_APP_NOT_FOUND); 265 } 266 267 /* 268 @case 4 installed type mimeType, preferred app, app type not 269 installed, app has signature 270 @results Should return B_OK and set the ref to refer to the 271 application's executable. Should install the app type and 272 set the app hint on it. 273 */ 274 static 275 void 276 CommonFindAppTest4(FindAppCaller &caller) 277 { 278 BRoster roster; 279 create_app(appFile1, appType1); 280 install_type(fileType1, appType1); 281 entry_ref ref; 282 CHK(caller(fileType1, &ref) == B_OK); 283 CHK(ref_for_path(appFile1) == ref); 284 check_app_type(appType1, appFile1); 285 } 286 287 /* 288 @case 5 installed type mimeType, preferred app, app type installed, 289 app has signature 290 @results Should return B_OK and set the ref to refer to the 291 application'sexecutable. Should set the app hint on the 292 app type. 293 */ 294 static 295 void 296 CommonFindAppTest5(FindAppCaller &caller) 297 { 298 BRoster roster; 299 create_app(appFile1, appType1, true); 300 install_type(fileType1, appType1); 301 entry_ref ref; 302 CHK(caller(fileType1, &ref) == B_OK); 303 CHK(ref_for_path(appFile1) == ref); 304 check_app_type(appType1, appFile1); 305 } 306 307 /* 308 @case 6 installed type mimeType, preferred app, app type installed, 309 app has signature, app has no execute permission 310 @results Should return B_OK and set the ref to refer to the 311 application's executable. Should set the app hint on the 312 app type. 313 */ 314 static 315 void 316 CommonFindAppTest6(FindAppCaller &caller) 317 { 318 BRoster roster; 319 create_app(appFile1, appType1, true, false); 320 install_type(fileType1, appType1); 321 entry_ref ref; 322 CHK(caller(fileType1, &ref) == B_OK); 323 CHK(ref_for_path(appFile1) == ref); 324 check_app_type(appType1, appFile1); 325 } 326 327 /* 328 @case 7 installed type mimeType, preferred app, app type installed, 329 two apps have the signature 330 @results Should return B_OK and set the ref to refer to the 331 application executable with the most recent modification 332 time. Should set the app hint on the app type. 333 */ 334 static 335 void 336 CommonFindAppTest7(FindAppCaller &caller) 337 { 338 BRoster roster; 339 create_app(appFile1, appType1); 340 create_app(appFile2, appType1, true); 341 set_file_time(appFile2, time(NULL) + 1); 342 install_type(fileType1, appType1); 343 entry_ref ref; 344 CHK(caller(fileType1, &ref) == B_OK); 345 CHK(ref_for_path(appFile2) == ref); 346 check_app_type(appType1, appFile2); 347 } 348 349 /* 350 @case 8 installed type mimeType, preferred app, app type installed, 351 two apps have the signature, one has a version info, the 352 other one is newer 353 @results Should return B_OK and set the ref to refer to the 354 application executable with version info. Should set the 355 app hint on the app type. 356 */ 357 static 358 void 359 CommonFindAppTest8(FindAppCaller &caller) 360 { 361 BRoster roster; 362 create_app(appFile1, appType1); 363 set_version(appFile1, 1); 364 create_app(appFile2, appType1, true); 365 set_file_time(appFile2, time(NULL) + 1); 366 install_type(fileType1, appType1); 367 entry_ref ref; 368 CHK(caller(fileType1, &ref) == B_OK); 369 CHK(ref_for_path(appFile1) == ref); 370 check_app_type(appType1, appFile1); 371 } 372 373 /* 374 @case 9 installed type mimeType, preferred app, app type installed, 375 two apps have the signature, both apps have a version info 376 @results Should return B_OK and set the ref to refer to the 377 application executable with the greater version. Should 378 set the app hint on the app type. 379 */ 380 static 381 void 382 CommonFindAppTest9(FindAppCaller &caller) 383 { 384 BRoster roster; 385 create_app(appFile1, appType1); 386 set_version(appFile1, 2); 387 create_app(appFile2, appType1, true); 388 set_version(appFile1, 1); 389 set_file_time(appFile2, time(NULL) + 1); 390 install_type(fileType1, appType1); 391 entry_ref ref; 392 CHK(caller(fileType1, &ref) == B_OK); 393 CHK(ref_for_path(appFile1) == ref); 394 check_app_type(appType1, appFile1); 395 } 396 397 /* 398 @case 10 installed type mimeType, preferred app, app type installed, 399 preferred app type has an app hint that points to an app 400 with a different signature 401 @results Should return B_OK and set the ref to refer to the 402 application's executable. Should remove the incorrect app 403 hint on the app type. (Haiku: Should set the correct app 404 hint. Don't even return the wrong app?) 405 */ 406 static 407 void 408 CommonFindAppTest10(FindAppCaller &caller) 409 { 410 BRoster roster; 411 create_app(appFile1, appType2); 412 set_type_app_hint(appType1, appFile1); 413 entry_ref appHint; 414 CHK(BMimeType(appType1).GetAppHint(&appHint) == B_OK); 415 install_type(fileType1, appType1); 416 entry_ref ref; 417 CHK(caller(fileType1, &ref) == B_OK); 418 CHK(ref_for_path(appFile1) == ref); 419 CHK(BMimeType(appType1).GetAppHint(&appHint) == B_ENTRY_NOT_FOUND); 420 // Haiku: We set the app hint for app type 2. There's no reason not to do it. 421 #ifdef TEST_R5 422 CHK(BMimeType(appType2).IsInstalled() == false); 423 #else 424 check_app_type(appType2, appFile1); 425 #endif 426 } 427 428 /* 429 @case 11 installed type mimeType, preferred app, app type installed, 430 preferred app type has an app hint pointing to void, 431 a differently named app with this signature exists 432 @results Should return B_OK and set the ref to refer to the 433 application's executable. Should update the app 434 hint on the app type. 435 */ 436 static 437 void 438 CommonFindAppTest11(FindAppCaller &caller) 439 { 440 BRoster roster; 441 create_app(appFile1, appType1); 442 set_type_app_hint(appType1, appFile2); 443 install_type(fileType1, appType1); 444 entry_ref ref; 445 CHK(caller(fileType1, &ref) == B_OK); 446 CHK(ref_for_path(appFile1) == ref); 447 check_app_type(appType1, appFile1); 448 } 449 450 /* 451 @case 12 mimeType is app signature, not installed 452 @results Should return B_OK and set the ref to refer to the 453 application executable. Should set the app hint on the 454 app type. 455 */ 456 static 457 void 458 CommonFindAppTest12(FindAppCaller &caller) 459 { 460 BRoster roster; 461 create_app(appFile1, appType1); 462 entry_ref ref; 463 CHK(caller(appType1, &ref) == B_OK); 464 CHK(ref_for_path(appFile1) == ref); 465 check_app_type(appType1, appFile1); 466 } 467 468 /* 469 @case 13 mimeType is installed, but has no preferred application, 470 super type has preferred application 471 @results Should return B_OK and set the ref to refer to the 472 application executable associated with the preferred app 473 of the supertype. Should set the app hint on the app type. 474 */ 475 static 476 void 477 CommonFindAppTest13(FindAppCaller &caller) 478 { 479 BRoster roster; 480 // make sure, the original preferred app for the "text" supertype is 481 // re-installed 482 struct TextTypeSaver { 483 TextTypeSaver() 484 { 485 BMimeType textType("text"); 486 hasPreferredApp 487 = (textType.GetPreferredApp(preferredApp) == B_OK); 488 } 489 490 ~TextTypeSaver() 491 { 492 BMimeType textType("text"); 493 textType.SetPreferredApp(hasPreferredApp ? preferredApp : NULL); 494 } 495 496 bool hasPreferredApp; 497 char preferredApp[B_MIME_TYPE_LENGTH]; 498 } _saver; 499 500 create_app(appFile1, appType1); 501 CHK(BMimeType("text").SetPreferredApp(appType1) == B_OK); 502 install_type(textTestType); 503 entry_ref ref; 504 CHK(caller(textTestType, &ref) == B_OK); 505 CHK(ref_for_path(appFile1) == ref); 506 check_app_type(appType1, appFile1); 507 } 508 509 /* 510 @case 14 installed type mimeType, preferred app, app type not installed, 511 app has signature, app is trash 512 @results Should return B_LAUNCH_FAILED_APP_IN_TRASH. 513 */ 514 static 515 void 516 CommonFindAppTest14(FindAppCaller &caller) 517 { 518 BRoster roster; 519 create_app(get_trash_app_file(), appType1); 520 install_type(fileType1, appType1); 521 entry_ref ref; 522 CHK(caller(fileType1, &ref) == B_LAUNCH_FAILED_APP_IN_TRASH); 523 } 524 525 /* 526 @case 15 installed type mimeType, preferred app, app type installed, 527 preferred app type has an app hint pointing to void, 528 no app with this signature exists 529 @results Should return B_LAUNCH_FAILED_APP_NOT_FOUND and unset the 530 app type's app hint. 531 */ 532 static 533 void 534 CommonFindAppTest15(FindAppCaller &caller) 535 { 536 BRoster roster; 537 set_type_app_hint(appType1, appFile1); 538 install_type(fileType1, appType1); 539 entry_ref ref; 540 CHK(caller(fileType1, &ref) == B_LAUNCH_FAILED_APP_NOT_FOUND); 541 entry_ref appHint; 542 CHK(BMimeType(appType1).GetAppHint(&appHint) == B_ENTRY_NOT_FOUND); 543 } 544 545 /* 546 @case 16 installed type mimeType, preferred app, app type installed, 547 preferred app type has an app hint pointing to a cyclic 548 link, no app with this signature exists 549 @results R5: Should return B_OK and set the ref to refer to the 550 link. 551 Haiku: Should return B_LAUNCH_FAILED_APP_NOT_FOUND and 552 unset the app type's app hint. 553 */ 554 static 555 void 556 CommonFindAppTest16(FindAppCaller &caller) 557 { 558 BRoster roster; 559 set_type_app_hint(appType1, appFile1); 560 install_type(fileType1, appType1); 561 system((string("ln -s ") + appFile1 + " " + appFile1).c_str()); 562 entry_ref ref; 563 entry_ref appHint; 564 #ifdef TEST_R5 565 CHK(caller(fileType1, &ref) == B_OK); 566 CHK(ref_for_path(appFile1, false) == ref); 567 CHK(BMimeType(appType1).GetAppHint(&appHint) == B_OK); 568 CHK(appHint == ref); 569 #else 570 CHK(caller(fileType1, &ref) == B_LAUNCH_FAILED_APP_NOT_FOUND); 571 CHK(BMimeType(appType1).GetAppHint(&appHint) == B_ENTRY_NOT_FOUND); 572 #endif 573 } 574 575 typedef void commonTestFunction(FindAppCaller &caller); 576 static commonTestFunction *commonTestFunctions[] = { 577 CommonFindAppTest1, CommonFindAppTest2, CommonFindAppTest3, 578 CommonFindAppTest4, CommonFindAppTest5, CommonFindAppTest6, 579 CommonFindAppTest7, CommonFindAppTest8, CommonFindAppTest9, 580 CommonFindAppTest10, CommonFindAppTest11, CommonFindAppTest12, 581 CommonFindAppTest13, CommonFindAppTest14, CommonFindAppTest15, 582 CommonFindAppTest16 583 }; 584 static int32 commonTestFunctionCount 585 = sizeof(commonTestFunctions) / sizeof(commonTestFunction*); 586 587 /* 588 status_t FindApp(const char *mimeType, entry_ref *app) const 589 @case 1 mimeType or app are NULL 590 @results Should return B_BAD_VALUE. 591 */ 592 void FindAppTester::FindAppTestA1() 593 { 594 BRoster roster; 595 CHK(roster.FindApp((const char*)NULL, NULL) == B_BAD_VALUE); 596 // R5: crashes when passing a non-NULL type, but a NULL ref. 597 #ifndef TEST_R5 598 CHK(roster.FindApp("image/gif", NULL) == B_BAD_VALUE); 599 #endif 600 entry_ref ref; 601 CHK(roster.FindApp((const char*)NULL, &ref) == B_BAD_VALUE); 602 } 603 604 /* 605 status_t FindApp(const char *mimeType, entry_ref *app) const 606 @case 2 mimeType is invalid 607 @results Should return B_BAD_VALUE. 608 */ 609 void FindAppTester::FindAppTestA2() 610 { 611 BRoster roster; 612 entry_ref ref; 613 CHK(roster.FindApp("invalid/mine/type", &ref) == B_BAD_VALUE); 614 } 615 616 // FindAppTypeCaller 617 class FindAppTypeCaller : public FindAppCaller { 618 public: 619 virtual status_t operator()(const char *type, entry_ref *ref) 620 { 621 BRoster roster; 622 return roster.FindApp(type, ref); 623 } 624 }; 625 626 /* 627 status_t FindApp(const char *mimeType, entry_ref *app) const 628 @case 3 FindApp(const char*, entry_ref*) cases 3-16 629 (== common cases 1-14) 630 */ 631 void FindAppTester::FindAppTestA3() 632 { 633 FindAppTypeCaller caller; 634 for (int32 i = 0; i < commonTestFunctionCount; i++) { 635 NextSubTest(); 636 (*commonTestFunctions[i])(caller); 637 tearDown(); 638 setUp(); 639 } 640 } 641 642 /* 643 status_t FindApp(entry_ref *ref, entry_ref *app) const 644 @case 1 ref or app are NULL 645 @results Should return B_BAD_VALUE. 646 */ 647 void FindAppTester::FindAppTestB1() 648 { 649 BRoster roster; 650 CHK(roster.FindApp((entry_ref*)NULL, NULL) == B_BAD_VALUE); 651 // R5: Crashes when passing a NULL (app) ref. 652 #ifndef TEST_R5 653 create_app(appFile1, appType1); 654 entry_ref fileRef(create_file(testFile1, fileType1, appType1)); 655 CHK(roster.FindApp(&fileRef, NULL) == B_BAD_VALUE); 656 #endif 657 entry_ref ref; 658 CHK(roster.FindApp((entry_ref*)NULL, &ref) == B_BAD_VALUE); 659 } 660 661 /* 662 status_t FindApp(entry_ref *ref, entry_ref *app) const 663 @case 2 ref doesn't refer to an existing entry => 664 @results Should return B_ENTRY_NOT_FOUND. 665 */ 666 void FindAppTester::FindAppTestB2() 667 { 668 BRoster roster; 669 entry_ref fileRef(ref_for_path(testFile1)); 670 entry_ref ref; 671 CHK(roster.FindApp(&fileRef, &ref) == B_ENTRY_NOT_FOUND); 672 } 673 674 /* 675 status_t FindApp(entry_ref *ref, entry_ref *app) const 676 @case 3 ref is valid, file has type and preferred app, preferred 677 app is in trash 678 @results Should return B_LAUNCH_FAILED_APP_IN_TRASH. 679 */ 680 void FindAppTester::FindAppTestB3() 681 { 682 BRoster roster; 683 create_app(get_trash_app_file(), appType1); 684 entry_ref fileRef(create_file(testFile1, fileType1, appType1)); 685 entry_ref ref; 686 CHK(roster.FindApp(&fileRef, &ref) == B_LAUNCH_FAILED_APP_IN_TRASH); 687 } 688 689 /* 690 status_t FindApp(entry_ref *ref, entry_ref *app) const 691 @case 4 ref is valid, file has type and preferred app, app type is 692 not installed, app exists and has signature 693 @results Should return B_OK and set the ref to refer to the file's 694 (not the file type's) preferred application's executable. 695 Should install the app type and set the app hint on it. 696 */ 697 void FindAppTester::FindAppTestB4() 698 { 699 BRoster roster; 700 create_app(appFile1, appType1); 701 create_app(appFile2, appType2); 702 install_type(fileType1, appType1); 703 entry_ref fileRef(create_file(testFile1, fileType1, appType2)); 704 entry_ref ref; 705 CHK(roster.FindApp(&fileRef, &ref) == B_OK); 706 CHK(ref_for_path(appFile2) == ref); 707 check_app_type(appType2, appFile2); 708 } 709 710 /* 711 status_t FindApp(entry_ref *ref, entry_ref *app) const 712 @case 5 ref is valid, file has no type, but preferred app, 713 app type is not installed, app exists and has signature 714 @results Should return B_OK and set the ref to refer to the 715 application's executable. Should install the app type and 716 set the app hint on it. 717 */ 718 void FindAppTester::FindAppTestB5() 719 { 720 BRoster roster; 721 create_app(appFile1, appType1); 722 entry_ref fileRef(create_file(testFile1, NULL, appType1)); 723 entry_ref ref; 724 CHK(roster.FindApp(&fileRef, &ref) == B_OK); 725 CHK(ref_for_path(appFile1) == ref); 726 check_app_type(appType1, appFile1); 727 } 728 729 /* 730 status_t FindApp(entry_ref *ref, entry_ref *app) const 731 @case 6 ref is valid, file has type and app hint, the type's 732 preferred app type is not installed, app exists and has 733 signature 734 @results Should return B_OK and set the ref to refer to the file 735 type's preferred application's executable. Should install 736 the app type and set the app hint on it. 737 */ 738 void FindAppTester::FindAppTestB6() 739 { 740 BRoster roster; 741 create_app(appFile1, appType1); 742 create_app(appFile2, appType2); 743 install_type(fileType1, appType1); 744 entry_ref fileRef(create_file(testFile1, fileType1, NULL, appFile2)); 745 entry_ref ref; 746 CHK(roster.FindApp(&fileRef, &ref) == B_OK); 747 CHK(ref_for_path(appFile1) == ref); 748 check_app_type(appType1, appFile1); 749 } 750 751 /* 752 status_t FindApp(entry_ref *ref, entry_ref *app) const 753 @case 7 ref is valid, file has type, the type's preferred app 754 type is not installed, app exists and has signature, 755 file is executable 756 @results Should return B_OK and set the ref to refer to the file. 757 Should not set the app hint on the app or file type (Why?). 758 */ 759 void FindAppTester::FindAppTestB7() 760 { 761 BRoster roster; 762 create_app(appFile1, appType1); 763 install_type(fileType1, appType1); 764 entry_ref fileRef(create_file(testFile1, fileType1)); 765 system((string("chmod a+x ") + testFile1).c_str()); 766 entry_ref ref; 767 CHK(roster.FindApp(&fileRef, &ref) == B_OK); 768 CHK(ref_for_path(testFile1) == ref); 769 CHK(BMimeType(appType1).IsInstalled() == false); 770 CHK(BMimeType(fileType1).GetAppHint(&ref) == B_ENTRY_NOT_FOUND); 771 } 772 773 /* 774 status_t FindApp(entry_ref *ref, entry_ref *app) const 775 @case 8 ref is valid and refers to a link to a file, file has type, 776 the type's preferred app type is not installed, 777 app exists and has signature 778 @results Should return B_OK and set the ref to refer to the file 779 type's preferred application's executable. Should install 780 the app type and set the app hint on it. 781 */ 782 void FindAppTester::FindAppTestB8() 783 { 784 BRoster roster; 785 create_app(appFile1, appType1); 786 install_type(fileType1, appType1); 787 create_file(testFile1, fileType1); 788 system((string("ln -s ") + testFile1 + " " + testLink1).c_str()); 789 entry_ref linkRef(ref_for_path(testLink1, false)); 790 entry_ref ref; 791 CHK(roster.FindApp(&linkRef, &ref) == B_OK); 792 CHK(ref_for_path(appFile1) == ref); 793 check_app_type(appType1, appFile1); 794 } 795 796 // FileWithTypeCaller 797 class FileWithTypeCaller : public FindAppCaller { 798 public: 799 virtual status_t operator()(const char *type, entry_ref *ref) 800 { 801 BRoster roster; 802 entry_ref fileRef(create_file(testFile1, type)); 803 return roster.FindApp(&fileRef, ref); 804 } 805 }; 806 807 /* 808 status_t FindApp(entry_ref *ref, entry_ref *app) const 809 @case 9 ref is valid, file has no type, sniffing results in a type, 810 type is set on file, 811 FindApp(const char*, entry_ref*) cases 4-16 812 (== common cases 2-14) 813 */ 814 void FindAppTester::FindAppTestB9() 815 { 816 FileWithTypeCaller caller; 817 for (int32 i = 0; i < commonTestFunctionCount; i++) { 818 NextSubTest(); 819 (*commonTestFunctions[i])(caller); 820 tearDown(); 821 setUp(); 822 } 823 } 824 825 // SniffFileTypeCaller 826 class SniffFileTypeCaller : public FindAppCaller { 827 public: 828 virtual status_t operator()(const char *type, entry_ref *ref) 829 { 830 BRoster roster; 831 entry_ref fileRef(create_file(testFile1, type, NULL, NULL, 832 "UnIQe pAtTeRn")); 833 install_type(fileType1, NULL, "1.0 [0] ('UnIQe pAtTeRn')"); 834 return roster.FindApp(&fileRef, ref); 835 } 836 }; 837 838 /* 839 status_t FindApp(entry_ref *ref, entry_ref *app) const 840 @case 10 ref is valid, file has no type, sniffing results in a type, 841 type is set on file, 842 FindApp(const char*, entry_ref*) cases 3-16 843 (== common cases 1-14) 844 */ 845 void FindAppTester::FindAppTestB10() 846 { 847 SniffFileTypeCaller caller; 848 for (int32 i = 1; i < commonTestFunctionCount; i++) { 849 NextSubTest(); 850 (*commonTestFunctions[i])(caller); 851 tearDown(); 852 setUp(); 853 } 854 } 855 856 /* 857 status_t FindApp(entry_ref *ref, entry_ref *app) const 858 @case 11 ref is valid and refers to a cyclic link 859 @results Should return B_LAUNCH_FAILED_NO_RESOLVE_LINK. 860 */ 861 void FindAppTester::FindAppTestB11() 862 { 863 BRoster roster; 864 system((string("ln -s ") + testLink1 + " " + testLink1).c_str()); 865 entry_ref linkRef(ref_for_path(testLink1, false)); 866 entry_ref ref; 867 CHK(roster.FindApp(&linkRef, &ref) == B_LAUNCH_FAILED_NO_RESOLVE_LINK); 868 } 869 870 /* 871 status_t FindApp(entry_ref *ref, entry_ref *app) const 872 @case 12 ref is valid and refers to a link to void 873 @results Should return B_LAUNCH_FAILED_NO_RESOLVE_LINK. 874 */ 875 void FindAppTester::FindAppTestB12() 876 { 877 BRoster roster; 878 system((string("ln -s ") + testFile1 + " " + testLink1).c_str()); 879 entry_ref linkRef(ref_for_path(testLink1, false)); 880 entry_ref ref; 881 CHK(roster.FindApp(&linkRef, &ref) == B_LAUNCH_FAILED_NO_RESOLVE_LINK); 882 } 883 884 885 Test* FindAppTester::Suite() 886 { 887 TestSuite* SuiteOfTests = new TestSuite; 888 889 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestA1); 890 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestA2); 891 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestA3); 892 893 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB1); 894 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB2); 895 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB3); 896 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB4); 897 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB5); 898 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB6); 899 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB7); 900 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB8); 901 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB9); 902 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB10); 903 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB11); 904 ADD_TEST4(BRoster, SuiteOfTests, FindAppTester, FindAppTestB12); 905 906 return SuiteOfTests; 907 } 908 909