Help me choose
Internship/2021 year-end summer internship

[WK6-M/T/W/Th/F] Redux, Configuration, Context, High order component, First bug ticket, Testing, Office life

by hajinny 2022. 1. 21.

Crap. It finally happened. I managed to push back my writing for a week (today is friday, and I didn't write any post since monday). 

 

I have an excuse though. I've been going to gym, meeting up some people, leetcoding sesh, and finally getting back to the office. Hold up, what? You are back at the office now? <= yes I am! Our team is going back on 3 days a week. 

0. Nontechnical debrief on my week

So yeah, the office is really nice. It's super big, and it's a lot bigger than I initially thought it would be. It comes with a pretty spacious kitchen, free brekkie (albeit just toast, cereal and coffie machine), and a lot of desks that you would see in a corporate. The turnout rate is super low, so it's mostly just few teams like ours that populate the office. 

 

Interns don't get a free parking, so it's $14 for the whole day if you are parking right beside the office. Although I started carpooling with two other interns who live pretty close (one lives somewhat far, but close enough - and another one is like 5 or 6 min away). 

 

Office life is alright, just a little bit tiring when you get back or when you get up. Had good moments mingling with other interns too, where we had a lunch together at some italian place! I probably wouldn't be able to get over the fact that two of the interns (who also happen to be my carpool buddies) had a vodka shot at the intern lunch... hehe, don't worry that's not the company culture they are just a little crazy! 

 

Interestingly, team culture is very different across teams. So my team is super focused and professional (which I do like), and some other teams are very laxed. It might as well be the case that your experience at the company would vary a lot depending on what team you land at.

 

On Thursday, I also got to meet a person whom I knew from the SESA event, who was also a software graduate. He sort of mentored me during the year, which was super helpful. It was just awesome to meet him within the office, sharing some talks as well. He's a really cool, mature person.

1. Waking up

I am starting to realize how much of a bless this work-from-home situation is. Saving 1 hour or so on commute is definitely not something that should be taken for granted, though mandatory wfh would be kinda depressing. So the mix is definitely the best.

2. Redux... context... configuration...

*This part is purely what I understood so far, and could be far from reality. Wait until I realize that my understanding was completely wrong and I remove this post.

2.1 Motivation 

The customer of the product I've been working on wanted the announcement banner to be non-dismissible. Announcement banner is that top bar thing that you can dismiss by clicking x. But since our product is being developed for a general use later on (as in, you can adopt the codebase for different themes for different customers), it was important to make this behaviour opt-in rather than one way (have x) or the other (don't have x). 

You know, something that looks like that

 

The idea was pretty simple, which was to introduce a global variable to the configuration and make that configuration state be passed onto the announcement banner, so that announcement banner will hide the x button if the configuration is set to have non-dismissable announcement (and vice versa). 

2.2 High-order component

general.js was a configuration file. 

// general.js

const general = {
    configA: true,
    configB: false,
    configC: "hello",
    ...
}

app.js would define an 'enhanced' top level component that had those states applied.

// app.js
import {selectors} from 'somewhere-related-to-redux'

const App = ({configA, configB, configC})=>{
    <stuff a={configA} b={configB} c={configC}>
    	<banner />
    </stuff>
}

const mapStateToProps = (state)=>{
    configA: selectors.getBootstrap(state).configA,
    configB: selectors.getBootstrap(state).configB,
    configC: selectors.getBootstrap(state).configC,
}

export default withConfigration(connect(mapStateToProps))(App)

So withConfiguration would take these states and return App component with those configs applied.

 

All I had to do was just do something like this:

// general.js

const general = {
    configA: true,
    configB: false,
    configC: "hello",
    announcementBannerIsDismissible: true
}
// app.js
import {selectors} from 'somewhere-related-to-redux'

const App = ({configA, configB, configC, announcementBannerIsDismissible})=>{
    <stuff a={configA} b={configB} c={configC}>
    	<banner closable={announcementBannerIsDismissible} />
    </stuff>
}

const mapStateToProps = (state)=>{
    configA: selectors.getBootstrap(state).configA,
    configB: selectors.getBootstrap(state).configB,
    configC: selectors.getBootstrap(state).configC,
    announcementBannerIsDismissible: selectors.getBootstrap(state).announcementBannerIsDismissible,
}

export default withConfigration(connect(mapStateToProps))(App)

2.3 PR

Here are things that happened while getting PR.

2.3.1 Boolean prop bug

const AnnouncementBannerContainer = ({closable, ...})=>(
    <container>
    	<AnnouncementBanner closable />
    </container>
)

const AnnouncementBanner = ({closable})=>{
    <a>
        //...
        {closable && <CloseIcon />}
    </a>
}

Can you spot a bug here?

 

The problem is that closable prop argument in AnnouncementBannerContainer doesn't actually get used by AnnouncementBanner. Here's the background: <A closable /> is equivalent to <A closable={true} /> - but that's clearly not what we want because the banner will be closable no matter what. So we want the following instead:

const AnnouncementBannerContainer = ({closable, ...})=>(
    <container>
    	<AnnouncementBanner closable={closable} />
    </container>
)

const AnnouncementBanner = ({closable})=>{
    <a>
        //...
        {closable && <CloseIcon />}
    </a>
}

2.3.2 Intuitive naming of variable

I originally had the variable named as announcementBannerDismissableEnabled. But clearly, announcementBannerIsDismissible is better. 

 

2.3.3 Redux wrapper

Redux is used to connect props to the App component. Selector is used to select props from global redux store. The PR comment was that rather than making App to grab announcementBannerIsDismissible and passing it to AnnouncementBanner all the way down. 

 

So it wasn't clear what redux wrapper meant, and I wasn't sure if it was lack of my understanding of redux (because I really haven't gone into studying redux that much) that made me unable to act on that comment. So I asked one of the team members what that meant, and the guy was really nice to walk through it with me. 

 

He suggested that it might be to do with Producer/Consumer, Context, Redux. Basically, Producer can define variable and functions and you can wrap a component with that producer. Any of the child component can use those variable and function by being wrapped around a consumer. Imagine that such producer of announcementBannerIsDismissible was already defined, then we would be able to do something like this:

 

import {ConfigConsumer} from 'somewhere'

const AnnouncementBannerContainer = ()=>{
    <ConfigConsumer>
    	(context)=>{
        	<AnnouncementBanner closable={context.announcementBannerIsDismissible} />
        }
    </ConfigConsumer>

}

Cool right? I should read up about context, producer and consumer more so I understand how it really works and so that I can actually use it myself! 

 

Anyways, that wasn't really what was needed to be done (ui components are meant to be dumb and not do something like fetching data themselves like that), and it was discovered later that the suffix 'Container' created the confusion that it must be a state provider that uses redux (but it's merely a ui-component).

3. Creating first bug ticket

So I implemented that ticket, and got PR merged, and the issue resolved. However, a bug was found by the test engineer where, even after the app is configured to have the Announcement Banner nondismissible, the announcement banner will have a small clickable area (that's invisible, but clickable and discoverable by pressing tab or hovering over that region).

 

The test engineer asked if the ticket should be reopened, and I thought it would need to be reopened and re-resolved. Then I wondered if PR has to be reopened and reapproved by people. It's good that I clarified whether the ticket should be reopened, because I was told not to reopen the ticket but instead raise a bug ticket so that it can be dealt with in the next sprint. At this point, we were on Thursday and Wednesday was meant to be a code freeze - and even so, there were some PRs left to be merged and the team was very hectic to create a release with important PRs approved. It was important that there were no more codes being introduced that can cause issues to a stable product later on. 

 

It was my first time in creating a bug ticket! The ticket just needed a title and related ticket which it concerns, and description such as that shown below:

+*Summary*+
+*How Found*+
+*Steps to reproduce*+
 # 
 # 
 # 
+*Expected Outcomes*+
 * 
+*Actual Outcomes*+
 *

 

4. Testing

I didn't exactly know what testing might entail with these web applications frontend. It turns out that it's whole lot of manual testings - I'd call it a user acceptance testing though it's a test engineer that would do the testing. While the testing process is not as concrete as expected vs actual numeral values might be, it was comprehensive enough to detect issues that could occur during demo or actual use.

 

There are mainly 4 things that I could understand as being tested:

- Accessibility (whether things can be keyboard navigated, and in user-accessible manner)

- Comparison with Figma mockup and prototype (prototype is very useful because it exactly shows how it should behave upon user interaction)

- Functional testing - Whether the implementation meets A/C written in the ticket (or if not present, things that the ticket purports to achieve)

- Nonfunctional testing (image below below)

What's A/C?
Nonfunctional testing

It does feel quite exhausting when you have to do this for Firefox, Mozilla, Microsoft Edge, Chrome. Trust me, I tried helping out our test engineer but ended up only seeing if it looks as what it is like on the figma. 

5. Office life

Here's a bit of stuff I've gathered as I was in the office for a bit.

1. Teams are different. There are good teams and bad teams, relaxed teams and professional teams, those with meetings everyday and those with one meeting fortnightly, those with stable product and those with an early stage product, etc. Mine felt like it was always on sprint (literally and figuratively), and all the processes and meetings were professional, which I really enjoyed to be honest. 

 

2. Small talks, regretfully, go a long way and you can't really avoid them. It's something I really struggle to do when there's a conversation already ongoing, since most of the times the stuffs that get mentioned are very boring and not something that I really know about. And when you are in the midst of a conversation that you know nothing about, there are three options: to flee, to stay and silently listen, to stay and somehow try to awkwardly talk, or to divert the conversation to a different topic that you know well and can enjoy talking about. Unfortunately I am one of the types that don't really have a super strong opinion on anything, neither do I want to stop someone enjoy talking what they are talking about (and I don't know how I might do that frankly, I need to observe others doing this so I can somehow 'control' or be part of the conversation). So anyways, that's bit of a thing that I thought about as I had a few chances to engage in small talks because of settings (you know, intern lunch, or just randomly catching someone in a group). But I also told myself not to feel bad for not being able to enjoy that conversation, because I know I don't enjoy it because I don't enjoy it and it's not that I have a problem - it's more that, out of manners, I should engage in it rather than avoid it. Who knows I might enjoy it? Though, one story is that one of the guy that was carpooling with me engaged in this small talk with some compsys engineer of some age and talked on and on that we left 1 hour after we finished our work (6 instead of 5pm) - it was about beer crafting, housing market, multiplier effects (you know, tax on spendings, tax on spendings of spendings...), markets to invest in, electric cars... which honestly I'm not too interested in hearing about from anyone who don't really hold expertise in them.

 

3. People prefer wfh for sure, and covid did change the landscape. Literally, 80-90% of people are not at the office at any given point in time.

 

4. It's somewhat hard to approach people in the team as an intern, when the whole team is busy. You know, you see people at work and you are kinda scared to talk to them. To be honest, I shouldn't be that shy and just make a conversation. I'll try do that as well.