Example #1
0
export function mapStateToProps(state: AppState, ownProps: InternalProps) {
  const { reviewId } = ownProps;
  const featuredReview = reviewId
    ? selectReview(state.reviews, reviewId)
    : null;

  return {
    featuredReview,
    loadingReview: reviewId
      ? state.reviews.view[reviewId] &&
        state.reviews.view[reviewId].loadingReview
      : false,
  };
}
  it('configures a rating component', () => {
    const { addon, review, store } = createStoreWithLatestReview();

    const root = render({ addon, store });

    expect(root.find(UserRating)).toHaveLength(1);
    expect(root.find(UserRating)).toHaveProp(
      'onSelectRating',
      root.instance().onSelectRating,
    );
    expect(root.find(UserRating)).toHaveProp(
      'review',
      selectReview(store.getState().reviews, review.id),
    );
  });
Example #3
0
function* manageAddonReview(
  action: CreateAddonReviewAction | UpdateAddonReviewAction,
  { _delay = delay }: Options = {},
) {
  const { body, errorHandlerId, score } = action.payload;
  const errorHandler = createErrorHandler(errorHandlerId);

  const savingRating = !!score;
  const savingReview = !!body;

  yield put(errorHandler.createClearingAction());
  if (savingRating) {
    yield put(flashReviewMessage(STARTED_SAVE_RATING));
  }
  if (savingReview) {
    yield put(flashReviewMessage(STARTED_SAVE_REVIEW));
  }

  try {
    const state: AppState = yield select(getState);
    const baseParams = {
      apiState: state.api,
      body,
      score,
    };
    let params;

    let oldReview = null;
    if (action.type === CREATE_ADDON_REVIEW) {
      params = {
        ...baseParams,
        addonId: action.payload.addonId,
        versionId: action.payload.versionId,
      };
    } else if (action.type === UPDATE_ADDON_REVIEW) {
      params = {
        ...baseParams,
        reviewId: action.payload.reviewId,
      };
      oldReview = selectReview(state.reviews, action.payload.reviewId);
      invariant(
        oldReview,
        `review with ID=${action.payload.reviewId} does not exist in state`,
      );
    }
    invariant(
      params,
      `params was unexpectedly empty; action.type: ${action.type}`,
    );

    const submitParams: SubmitReviewParams = params;
    const reviewFromResponse: SubmitReviewResponse = yield call(
      submitReview,
      submitParams,
    );

    yield put(setReview(reviewFromResponse));

    if (savingRating) {
      yield put(flashReviewMessage(SAVED_RATING));
    }
    if (savingReview) {
      yield put(flashReviewMessage(SAVED_REVIEW));
      yield put(hideEditReviewForm({ reviewId: reviewFromResponse.id }));
    }

    if (!reviewFromResponse.is_developer_reply) {
      yield put(
        setLatestReview({
          addonId: reviewFromResponse.addon.id,
          review: reviewFromResponse,
          userId: reviewFromResponse.user.id,
        }),
      );

      yield put(
        updateRatingCounts({
          addonId: reviewFromResponse.addon.id,
          oldReview,
          newReview: createInternalReview(reviewFromResponse),
        }),
      );
    }

    // Make the message disappear after some time.
    yield _delay(FLASH_SAVED_MESSAGE_DURATION);
    yield put(hideFlashedReviewMessage());
  } catch (error) {
    log.warn(
      `Failed to create/update review with action ${action.type}: ${error}`,
    );
    yield put(errorHandler.createErrorAction(error));
    yield put(flashReviewMessage(ABORTED));
  }
}