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