In brief: There seems to be an issue with \Magento\Catalog\Model\ProductRepository whereby it does not respect emulation, nor does it correctly identify the current scope in all situations.
The primary result of this when saving a product through ProductRepository from an affected scope is that (1) some attributes are saved in the fallback scope (default store) when that would not be expected, and (2) it seems to be impossible to associate a product to multiple websites.
Magento version: EE 2.0.2
Context: A custom controller in the admin panel extending \Magento\Backend\App\Action, for importing configurable products.
Tracing the issue:
\Magento\Catalog\Api\ProductRepositoryInterface is injected into the controller via DI.
We load $product, already having website_ids = [1, 2] (for reasons unclear, these are not returned by $product->getWebsiteIds().)
We call $this->productRepository->save($product);\Magento\Catalog\Model\ProductRepository::save() calls
Having no currentStoreId, StoreManager calls
StoreManager->storeResolver->getCurrentStoreId() (\Magento\Store\Model\StoreResolver) calls
StoreResolver->getStoresData()StoreResolver was initialized by DI with no runMode or scopeCode, therefore $this->runMode defaults to 'website', and $this->scopeCode defaults to 'null'.
With this state, StoreResolver::getStoresData() returns:
$store is loaded based on $defaultStoreId and returned to ProductRepository.
Bottom line: This results in ProductRepository->storeManager->getStore()->getCode() returning 'default', despite that we are in the admin scope.
Starting emulation on the admin store prior to this process has no bearing on the outcome.
Passing in a parameter of ___store='admin' has no bearing on the outcome (because admin is not a valid website code).
Expected behavior is that ProductRepository obeys the scope of whatever context it is called from, including emulation.